package com.xyf.sys.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.lop.open.api.sdk.domain.ECAP.CommonCreateOrderApi.commonCheckPreCreateOrderV1.CommonCheckPreCreateOrderResponse;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.service.payrollcard.PayrollCardService;
import com.wechat.pay.java.service.payrollcard.model.AuthType;
import com.wechat.pay.java.service.payrollcard.model.CreateTransferBatchRequest;
import com.wechat.pay.java.service.payrollcard.model.TransferBatchEntity;
import com.wechat.pay.java.service.payrollcard.model.TransferDetailInput;
import com.wechat.pay.java.service.profitsharing.ProfitsharingService;
import com.wechat.pay.java.service.profitsharing.model.*;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import com.wechat.pay.java.service.refund.model.Status;
import com.xyf.sys.config.CustomException;
import com.xyf.sys.config.MiniprogramConfig;
import com.xyf.sys.config.WxConfig;
import com.xyf.sys.domain.*;
import com.xyf.sys.enums.DeliveryEnum;
import com.xyf.sys.enums.LogisticsEventEnum;
import com.xyf.sys.mapper.GoodsCartItemMapper;
import com.xyf.sys.mapper.GoodsCartMapper;
import com.xyf.sys.mapper.OrderMapper;
import com.xyf.sys.service.*;
import com.xyf.sys.util.CommonUtils;
import com.xyf.sys.util.JDComputeChargeUtils;
import com.xyf.sys.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author R-H
 * @Date 2024/2/241749
 * @Description
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class OrderServiceImpl implements IOrderService {
    private static final int CODE_NUMBER_LENGTH = 6;
    private static final String UPPER_CASE_ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String PHONE_NUMBER_PATTERN = "^1[3-9]\\d{9}$";

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private IWechatService wechatService;
    @Autowired
    private IUserService userService;
    @Lazy
    @Autowired
    private ILogisticService logisticService;
    @Autowired
    private IOrderProductService orderProductService;
    @Autowired
    private IOrderAddressService orderAddressService;
    @Autowired
    private ISysPriceSchemeService priceSchemeService;
    @Autowired
    private WxConfig wxConfig;
    @Autowired
    @Qualifier(value = "clientConfig")
    private MiniprogramConfig.MiniConfig clientConfig;
    @Autowired
    @Qualifier(value = "manageConfig")
    private MiniprogramConfig.MiniConfig manageConfig;
    @Autowired
    private ICartItemService cartItemService;
    @Autowired
    private IProductService productService;
    @Autowired
    private IUserAddressService userAddressService;
    @Autowired
    private IOrderLogisticsService orderLogisticsService;
    @Autowired
    private IUserOrderEventService userOrderEventService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IProductOptionService productOptionService;
    @Autowired
    private IRegimentAssistService regimentAssistService;
    @Autowired
    private IOrderProfitsharingService orderProfitsharingService;
    @Autowired
    private IOrderProfitsharingReceiverService orderProfitsharingReceiverService;
    @Autowired
    private ProfitsharingService profitsharingService;
    @Autowired
    private PayrollCardService payrollCardService;
    @Autowired
    private GoodsCartItemMapper goodsCartItemMapper;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private GoodsCartMapper goodsCartMapper;
    @Autowired
    private IOrderProductCodeService orderProductCodeService;
    @Autowired
    private IDeptService deptService;
    @Autowired
    private TaskScheduler taskScheduler;


    @Override
    public Object preOrder(PreOrderVo orderVo) {
        log.info("预订单 body {}", JSONObject.toJSONString(orderVo));
        User user = userService.get(orderVo.getUserId());
        Order order = null;
        if (StringUtils.isNotBlank(orderVo.getOrderId())) {
            order = this.get(orderVo.getOrderId());
            if ("1".equals(order.getDelFlag())) {
                throw new CustomException("该订单已被删除");
            }
            if (order.getPayStatus() == 1) {
                throw new CustomException("该订单已支付");
            }
            List<OrderAddress> addressList = orderAddressService.getAddressList(order.getId());
            List<OrderProduct> productList = orderProductService.getOrderProductList(order.getId());
            addressList.stream().forEach(address -> address.setDelFlag("1"));
            orderAddressService.batchUpdate(addressList);
            productList.stream().forEach(orderProduct -> {
                orderProduct.setDelFlag("1");
                orderProductService.update(orderProduct);
            });
        } else {
            order = new Order();
            Date date = new Date();
            order.setId(IdUtil.getSnowflakeNextIdStr());
            order.setOrderTime(new Date());
            order.setOutTradeNo(this.generateOrderOutTradeNo(orderVo.getMobile(), date.getTime()));
            order.setAppid(orderVo.getFromAppid());
            order.setMobile(orderVo.getMobile());
            order.setPickUpType(orderVo.getPickUpType());
            order.setProductCategory(orderVo.getProductCategory());
            order.setRegimentId(orderVo.getRegimentId());
            order.setUserId(orderVo.getUserId());
            order.setDeptId(user.getDeptId());
            if (clientConfig.getAppid().equals(orderVo.getFromAppid())){
                Dept dept = deptService.get(user.getDeptId());
                order.setRegimentId(dept.getLeader());
            } else {
                order.setRegimentId(user.getId());
            }
            order.setCreateBy(orderVo.getUserId());
            order.setCreateTime(date);
        }
        order.setPayStatus(0);
        order.setOrderType(1);
        order.setOrderStatus(1);
        order.setTotalPrice(BigDecimal.ZERO);
        if (manageConfig.getAppid().equals(orderVo.getFromAppid())) {
            order.setTotalPrice(new BigDecimal(orderVo.getTotalPrice()));
        }
        order.setPrinterId(orderVo.getPrinterId());
        if (orderVo.getPrintTimes() != null) {
            int printTimes = order.getPrintTimes() == null ? 0 : order.getPrintTimes();
            order.setPrintTimes(printTimes + 1);
        }
        order.setLastUpdateTime(new Date());
        List<PreOrderProduct> productList = orderVo.getProductList();
        List<OrderProduct> orderProducts = new ArrayList<>(productList.size());
        for (PreOrderProduct product : productList) {
            OrderProduct orderProduct = new OrderProduct();
            long id = IdUtil.getSnowflakeNextId();
            orderProduct.setId(String.valueOf(id));
            orderProduct.setCode(convertToFixedLengthHash(id));
            orderProduct.setOrderId(order.getId());
            orderProduct.setBizId(product.getBizId());
            orderProduct.setUserId(order.getUserId());
            orderProduct.setDeliveryName(product.getDeliveryName());
            orderProduct.setDeliveryId(product.getDeliveryId());
            orderProduct.setExpressType(product.getExpressType());
            orderProduct.setItemType(product.getItemType());
            orderProduct.setItemNotes(product.getItemNotes());
            orderProduct.setWeight(product.getWeight());
            orderProduct.setPrice(BigDecimal.ZERO);
            orderProduct.setTotalPrice(BigDecimal.ZERO);
            orderProduct.setPickUpPrice(BigDecimal.ZERO);
            if (manageConfig.getAppid().equals(orderVo.getFromAppid())) {
                orderProduct.setPrice(Objects.isNull(product.getPrice()) ? BigDecimal.ZERO : new BigDecimal(product.getPrice()));
                orderProduct.setTotalPrice(new BigDecimal(product.getTotalPrice()));
            }
            orderProduct.setPickUpType(orderVo.getPickUpType());
            if (product.getPickUpPrice() != null) {
                orderProduct.setPickUpPrice(new BigDecimal(product.getPickUpPrice()));
            }
            orderProduct.setLogisticPriceSchemeId(product.getLogisticPriceSchemeId());
            orderProduct.setLastUpdateTime(new Date());
            orderProduct.setCreateTime(new Date());
            orderProduct.setStatus("0");
            orderProduct.setDelFlag("0");
            orderProducts.add(orderProduct);
            UserAddress sendMan = product.getSendMan();
            UserAddress recMan = product.getRecMan();
            OrderAddress sendManAddress = new OrderAddress();
            sendManAddress.setOrderProductId(orderProduct.getId());
            sendManAddress.setMobile(sendMan.getMobile());
            sendManAddress.setOrderId(order.getId());
            sendManAddress.setUserId(order.getUserId());
            sendManAddress.setProvince(sendMan.getProvince());
            sendManAddress.setCity(sendMan.getCity());
            sendManAddress.setArea(sendMan.getArea());
            sendManAddress.setAddress(sendMan.getAddress());
            sendManAddress.setName(sendMan.getName());
            sendManAddress.setRealId(sendMan.getRealId());
            sendManAddress.setRealName(sendMan.getRealName());
            sendManAddress.setType(1);
            sendManAddress.setLastUpdateTime(new Date());
            sendManAddress.setCreateBy(order.getUserId());
            sendManAddress.setCreateTime(new Date());
            sendManAddress.setStatus("0");
            sendManAddress.setDelFlag("0");
            orderAddressService.save(sendManAddress);
            order.setDescribe("快递发往-" + sendManAddress.getProvince() + sendManAddress.getCity());
            orderProduct.setDescribe("快递发往-" + sendManAddress.getProvince() + sendManAddress.getCity());
            OrderAddress recManAddress = new OrderAddress();
            recManAddress.setOrderProductId(orderProduct.getId());
            recManAddress.setMobile(recMan.getMobile());
            recManAddress.setOrderId(order.getId());
            recManAddress.setUserId(order.getUserId());
            recManAddress.setProvince(recMan.getProvince());
            recManAddress.setCity(recMan.getCity());
            recManAddress.setArea(recMan.getArea());
            recManAddress.setAddress(recMan.getAddress());
            recManAddress.setName(recMan.getName());
            recManAddress.setType(2);
            recManAddress.setLastUpdateTime(new Date());
            recManAddress.setCreateBy(order.getUserId());
            recManAddress.setCreateTime(new Date());
            recManAddress.setStatus("0");
            recManAddress.setDelFlag("0");
            orderAddressService.save(recManAddress);
            orderProductService.save(orderProduct);
        }
        if (StringUtils.isBlank(orderVo.getOrderId())) {
            this.create(order);
        } else {
            order.setUpdateBy(orderVo.getUserId());
            order.setUpdateTime(new Date());
            this.update(order);
        }
        PreOrderResponseVo pay = this.pay(order.getId(), orderVo.getUserId(), orderVo.getFromAppid());
        if (StringUtils.isBlank(orderVo.getOrderId()) && clientConfig.getAppid().equals(order.getAppid())) {
            if (order.getOrderType() == 1) {
                List<User> userList = userService.getUserList(manageConfig.getAppid(), order.getDeptId());
                order = this.get(order.getId());
                for (User u : userList) {
                    if (StringUtils.isNotBlank(u.getUnionid())) {
                        User accountUser = userService.getUser(u.getUnionid(), "wxa33105ce83dddd01");
                        if (accountUser != null) {
                            try {
                                JSONObject object = wechatService.sendDeliveryOrderNotifyTemplateMessage("wxa33105ce83dddd01", "5506a050467515ccdb28c44f6a25f652", "zWGtUKMoqzHokpuxcLtP2-wRmYgeycroC8ygfcpkna0", accountUser.getOpenid(), order, user.getName() == null ? user.getMobile() : user.getName(), user.getMobile());
                                if (object != null && object.getInteger("errcode") == 0) {
                                    log.info("sendDeliveryOrderNotifyTemplateMessage template message send to touser {} success ", u.getOpenid());
                                } else {
                                    log.error("sendDeliveryOrderNotifyTemplateMessage template message send err {}", object.toString());
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("sendDeliveryOrderNotifyTemplateMessage delivery template message err {}", e);
                            }
                        } else {
                            log.warn("order id not found public account user {} openid {} ", order.getId(), order.getRegimentId());
                        }
                    }
                }
            }
        }
        return pay;
    }

    @Override
    public boolean callback(Transaction transaction) {
        Order order = orderMapper.selectByOutTradeNo(transaction.getOutTradeNo());
        log.info("订单支付回调 {}", JSONObject.toJSONString(transaction));
        if (order == null) {
            return false;
        }
        order.setCallbackTime(new Date());
        Transaction.TradeStateEnum tradeState = transaction.getTradeState();
        if (Transaction.TradeStateEnum.SUCCESS.equals(tradeState)) {
            order.setTransactionId(transaction.getTransactionId());
            order.setPayStatus(1);
            order.setOrderStatus(2);
            if (StringUtils.isNotBlank(transaction.getPayer().getSubOpenid())){
                order.setPayerId(transaction.getPayer().getSubOpenid());
            }
            order.setCallbackTime(new DateTime(transaction.getSuccessTime()).toDate());
        } else {
            order.setPayStatus(2);
        }
        order.setLastUpdateTime(new Date());
        // 查询团长
        if (clientConfig.getAppid().equals(order.getAppid())) {
            if (order.getOrderType() == 1) {
                List<User> userList = userService.getUserList(manageConfig.getAppid(), order.getDeptId());
                for (User u : userList) {
                    if (StringUtils.isNotBlank(u.getUnionid())) {
                        User accountUser = userService.getUser(u.getUnionid(), "wxa33105ce83dddd01");
                        if (accountUser != null) {
                            try {
                                OrderVo detail = this.getDetail(order.getId());
                                JSONObject object = wechatService.sendDeliveryOrderTemplateMessage("wxa33105ce83dddd01", "5506a050467515ccdb28c44f6a25f652", "PXXa6CrpqVd5qkUd6niLUC7wqVyLPk8SgpECTq9b-Uc", accountUser.getOpenid(), detail);
                                if (object != null && object.getInteger("errcode") == 0) {
                                    log.info("delivery template message send to touser {} success ", u.getOpenid());
                                } else {
                                    log.error("delivery template message send err {}", object.toString());
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("send delivery template message err {}", e);
                            }
                        } else {
                            log.warn("order id not found public account user {} openid {} ", order.getId(), order.getRegimentId());
                        }
                    }
                }
            }
        }
        if (order.getOrderType() == 2){
            taskScheduler.schedule(
                    () -> {
                        order.setDeliveryStatus(1);
                        try {
                            sendLaundryShippingMessage(order.getId());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    },
                    Instant.now().plusSeconds(120)
            );
        }
        if (order.getOrderType() == 3) {
            List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
            RegimentAssist assist = regimentAssistService.get(orderProductList.get(0).getAssistId());
            assist.setStatus("2");
            User user = userService.get(assist.getUserId());
            orderProfitsharingReceiverService.addProfitsharingReceiver(ReceiverType.MERCHANT_ID.toString(), wxConfig.getLaundryMerchant().getMchid(), "延安市宝塔区楷奕喜洗衣店（个体工商户）", ReceiverRelationType.SERVICE_PROVIDER.toString(), null, new BigDecimal("0.01"), order.getId());
            orderProfitsharingReceiverService.addProfitsharingReceiver(ReceiverType.PERSONAL_OPENID.toString(), user.getId(), user.getRealName(), ReceiverRelationType.USER.toString(), null, new BigDecimal("0.29"), order.getId());
            regimentAssistService.update(assist);
        }
        if (order.getOrderType() == 4) {
            List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
            for (OrderProduct orderProduct : orderProductList) {
//                GoodsCartItem cartItem = goodsCartItemMapper.selectByPrimaryKey(orderProduct.getCartItemId());
                Goods goods = goodsService.get(orderProduct.getProductId());
                Integer stock = goods.getStock();
                Integer quantity = 1;
                goods.setStock(stock - quantity);
                if (goods.getStock() <= 0) {
                    goods.setStatus((byte) -1);
                }
                goodsService.update(goods);
//                cartItem.setStatus("1");
//                cartItem.setUpdateTime(new Date());AutoCertificateService
//                goodsCartItemMapper.updateByPrimaryKey(cartItem);
//                GoodsCart cart = goodsCartMapper.selectByPrimaryKey(cartItem.getGoodsCartId());
//                cart.setStatus("1");
//                cart.setUpdateTime(new Date());
//                goodsCartMapper.updateByPrimaryKey(cart);
            }
        }
        return this.update(order) > 0;
    }

    @Override
    public boolean refundNotification(RefundNotification transaction) {
        log.info("订单退款回调 {}", JSONObject.toJSONString(transaction));
        Order order = orderMapper.selectByOutRefundNo(transaction.getOutRefundNo());
        if (order == null) {
            return false;
        }
        order.setRefundCallbackTime(new Date());
        Status refundStatus = transaction.getRefundStatus();
        order.setRefundTransactionId(transaction.getTransactionId());
        if (Status.PROCESSING.equals(refundStatus)) {
            order.setRefundStatus(1);
        }
        if (Status.SUCCESS.equals(refundStatus)) {
            order.setRefundStatus(2);
        }
        if (Status.ABNORMAL.equals(refundStatus)) {
            order.setRefundStatus(3);
        }
        if (Status.CLOSED.equals(refundStatus)) {
            order.setRefundStatus(4);
        }
        order.setOrderStatus(4);
        order.setLastUpdateTime(new Date());
        return this.update(order) > 0;
    }

    @Override
    public String generateOrderOutTradeNo(String mobile, Long timestamp) {
        return Long.toString(Long.parseLong(mobile.replaceAll("[^0-9]", "")), 36) + "_" + Long.toString(timestamp / 1000, 36);
    }

    @Override
    public OrderPreviewVo previewPrice(OrderPreviewVo orderPreview) {
        String openid = orderPreview.getUserId();
        // 查询用户团长
        User user = userService.get(openid);
        if (user.getDeptId() == null) {
            throw new CustomException("未选择站点");
        }
        List<OrderProductPreviewRequestVo> orderProductList = orderPreview.getProductList();
        for (OrderProductPreviewRequestVo productPreview : orderProductList) {
            PriceScheme priceScheme = priceSchemeService.get(productPreview.getLogisticPriceSchemeId());
            productPreview.setPickUpPrice(0);
            String province = productPreview.getReceiveProvince();
            BigDecimal weight = productPreview.getWeight();
            BigDecimal calculateWeight = weight.setScale(0, RoundingMode.UP);

            String deliveryId = productPreview.getDeliveryId();
            if (DeliveryEnum.JD.toString().equals(deliveryId)) {
                if ("2".equals(productPreview.getExpressType())
                        && !productPreview.getReceiveProvince().contains("西藏") && !productPreview.getReceiveProvince().contains("新疆")) {
                    Double charge = JDComputeChargeUtils.computeCharge(weight.doubleValue(), productPreview.getReceiveProvince());
                    productPreview.setPrice(new BigDecimal(charge).multiply(new BigDecimal("100")).intValue());
                    productPreview.setTotalPrice(productPreview.getPrice());
                    Integer totalPrice = orderPreview.getTotalPrice() == null ? 0 : orderPreview.getTotalPrice();
                    orderPreview.setTotalPrice(totalPrice + productPreview.getPrice());
                } else {
                    CommonCheckPreCreateOrderResponse orderResponse = logisticService.jdPreCheck(productPreview.getDeliveryId(), productPreview.getSenderAddress(), productPreview.getReceiverAddress(), productPreview.getItemType(), productPreview.getQuantity(), productPreview.getVolume(), productPreview.getWeight(), productPreview.getExpressType());
                    if (orderResponse != null) {
                        productPreview.setPrice(orderResponse.getTotalFreightPre().multiply(new BigDecimal("100")).intValue());
                        Integer pickUpPrice = productPreview.getPickUpPrice() == null ? 0 : productPreview.getPickUpPrice();
                        productPreview.setTotalPrice(productPreview.getPrice() + pickUpPrice);
                        Integer totalPrice = orderPreview.getTotalPrice() == null ? 0 : orderPreview.getTotalPrice();
                        orderPreview.setTotalPrice(totalPrice + productPreview.getPrice());
                    }
                }
            } else if (DeliveryEnum.SF.toString().equals(deliveryId)) {
                JSONObject jsonObject = logisticService.sfExpressQueryDelivertm(productPreview.getExpressType(), weight, DateUtil.now(), "1", productPreview.getReceiverAddress(), productPreview.getSenderAddress());
                if (jsonObject == null) {
                    throw new CustomException("查询失败");
                }
                JSONArray deliverTmDto = jsonObject.getJSONArray("deliverTmDto");
                for (int i = 0; i < deliverTmDto.size(); i++) {
                    JSONObject deliverTm = deliverTmDto.getJSONObject(i);
                    if (deliverTm.getString("businessType") != null && deliverTm.getString("businessType").equals(productPreview.getExpressType())) {
                        if (StringUtils.isBlank(deliverTm.getString("fee"))) {
                            throw new CustomException("特快不支持查询价格");
                        }
                        int price = deliverTm.getBigDecimal("fee").multiply(new BigDecimal("100")).setScale(0, RoundingMode.UP).intValue();
                        productPreview.setPrice(price);
                        Integer pickUpPrice = productPreview.getPickUpPrice() == null ? 0 : productPreview.getPickUpPrice();
                        productPreview.setTotalPrice(productPreview.getPrice() + pickUpPrice);
                        Integer totalPrice = orderPreview.getTotalPrice() == null ? 0 : orderPreview.getTotalPrice();
                        orderPreview.setTotalPrice(totalPrice + productPreview.getPrice());
                    }
                }
            } else if (DeliveryEnum.EMS.toString().equals(deliveryId)) {
                productPreview.setPrice(calculateEMSCost(calculateWeight.intValue(), province, deliveryId));
                Integer pickUpPrice = productPreview.getPickUpPrice() == null ? 0 : productPreview.getPickUpPrice();
                productPreview.setTotalPrice(productPreview.getPrice() + pickUpPrice);
                Integer totalPrice = orderPreview.getTotalPrice() == null ? 0 : orderPreview.getTotalPrice();
                orderPreview.setTotalPrice(totalPrice + productPreview.getPrice());
            } else if(DeliveryEnum.JTSD.toString().equals(deliveryId)) {
                productPreview.setPrice(calculateMethodAOrderPrice_JTSD(calculateWeight.intValue(), province, deliveryId));
                Integer pickUpPrice = productPreview.getPickUpPrice() == null ? 0 : productPreview.getPickUpPrice();
                productPreview.setTotalPrice(productPreview.getPrice() + pickUpPrice);
                Integer totalPrice = orderPreview.getTotalPrice() == null ? 0 : orderPreview.getTotalPrice();
                orderPreview.setTotalPrice(totalPrice + productPreview.getPrice());
            } else if ("方案一".equals(priceScheme.getName())) {
                productPreview.setPrice(calculateMethodAOrderPrice(calculateWeight.intValue(), province, deliveryId));
                Integer pickUpPrice = productPreview.getPickUpPrice() == null ? 0 : productPreview.getPickUpPrice();
                productPreview.setTotalPrice(productPreview.getPrice() + pickUpPrice);
                Integer totalPrice = orderPreview.getTotalPrice() == null ? 0 : orderPreview.getTotalPrice();
                orderPreview.setTotalPrice(totalPrice + productPreview.getPrice());
            } else {
                productPreview.setPrice(calculateMethodBOrderPrice(calculateWeight.intValue(), province, deliveryId));
                Integer pickUpPrice = productPreview.getPickUpPrice() == null ? 0 : productPreview.getPickUpPrice();
                productPreview.setTotalPrice(productPreview.getPrice() + pickUpPrice);
                Integer totalPrice = orderPreview.getTotalPrice() == null ? 0 : orderPreview.getTotalPrice();
                orderPreview.setTotalPrice(totalPrice + productPreview.getPrice());
            }
        }

        return orderPreview;
    }

    @Override
    public Boolean edit(OrderVo body) {
        log.info("order body {}", JSONObject.toJSONString(body));
        Order order = this.get(body.getId());
        if (order.getOrderType() == 1) {
            order.setTotalPrice(body.getTotalPrice());
            order.setPrinterId(body.getPrinterId());
            if (body.getPrintTimes() != null) {
                int printTimes = order.getPrintTimes() == null ? 0 : order.getPrintTimes();
                order.setPrintTimes(printTimes + 1);
            }
            if (!CollectionUtils.isEmpty(body.getProductList())) {
                for (OrderProduct orderProduct : body.getProductList()) {
                    OrderProduct product = orderProductService.get(orderProduct.getId());
                    product.setDescribe(orderProduct.getDescribe());
                    product.setItemType(orderProduct.getItemType());
                    product.setItemNotes(orderProduct.getItemNotes());
                    product.setWeight(orderProduct.getWeight());
                    product.setPrice(orderProduct.getPrice());
                    product.setPickUpType(orderProduct.getPickUpType());
                    product.setPickUpPrice(orderProduct.getPickUpPrice());
                    product.setTotalPrice(orderProduct.getTotalPrice());
                    product.setDeliveryId(orderProduct.getDeliveryId());
                    product.setDeliveryName(orderProduct.getDeliveryName());
                    product.setUpdateBy(body.getUserId());
                    product.setUpdateTime(new Date());
                    orderProductService.update(product);
                }
            }
        } else {
            List<OrderProduct> orderProducts = new ArrayList<>(8);
            BigDecimal totalPrice = BigDecimal.ZERO;
            for (SysCartItem cartItem : body.getCartItems()) {
                OrderProduct orderProduct = new OrderProduct();
                long id = IdUtil.getSnowflakeNextId();
                orderProduct.setId(String.valueOf(id));
                orderProduct.setCode(convertToFixedLengthHash(id));
                orderProduct.setOrderId(order.getId());
                orderProduct.setUserId(body.getUserId());
                orderProduct.setCartItemId(cartItem.getId());
                orderProduct.setProductId(cartItem.getProductId());
                BigDecimal price = cartItem.getTotalPrice();
                orderProduct.setTotalPrice(price);
                orderProduct.setPickUpPrice(BigDecimal.ZERO);
                orderProduct.setLastUpdateTime(new Date());
                orderProduct.setCreateTime(new Date());
                orderProduct.setStatus("0");
                orderProduct.setDelFlag("0");
                orderProducts.add(orderProduct);
                totalPrice = totalPrice.add(price);
                orderProductService.save(orderProduct);
            }
            order.setTotalPrice(totalPrice);
        }
        order.setUpdateBy(body.getUserId());
        order.setUpdateTime(new Date());
        return this.update(order) > 0;
    }


    @Override
    public Order get(String orderId) {
        return orderMapper.selectByPrimaryKey(orderId);
    }

    @Override
    public Order create(Order order) {
        order.setDelFlag("0");
        return orderMapper.insert(order) > 0 ? order : null;
    }

    @Override
    public int update(Order order) {
        order.setLastUpdateTime(new Date());
        return orderMapper.updateByPrimaryKey(order);
    }

    @Override
    public PreOrderResponseVo pay(String orderId, String userId, String appid) {
        Order order = this.get(orderId);
        if (order.getPayStatus() == 1){
            throw new CustomException("该订单已支付，请查看\"已付款\"列表");
        }
        List<OrderProduct> productList = orderProductService.getOrderProductList(orderId);
        if (BigDecimal.ZERO.compareTo(order.getTotalPrice()) == -1 && order.getPayStatus() == 0) {
            String outTradeNo = this.generateOrderOutTradeNo(order.getMobile(), System.currentTimeMillis());
            PreOrderResponseVo prepay = wechatService.pay(appid == null ? order.getAppid() : appid, order.getOrderType() == 1 ? wxConfig.getSubMchid() : wxConfig.getLaundryMerchant().getMchid(), order.getTotalPrice().intValue(), userId, outTradeNo, order.getOrderType() == 1 ? productList.get(0).getDescribe() : "团购商品", false);
            prepay.setOrderId(orderId);
            prepay.setOutTradeNo(outTradeNo);
            order.setOutTradeNo(outTradeNo);
            order.setPayerId(userId);
            this.update(order);
            return prepay;
        }
        PreOrderResponseVo responseVo = new PreOrderResponseVo();
        responseVo.setOrderId(orderId);
        return responseVo;
    }

    @Override
    public PreOrderResponseVo pay(String orderId, String userId) {
        return pay(orderId, userId, null);
    }

    @Override
    public List<OrderVo> getList(OrderListRequestVo requestVo) {
        requestVo.setDelFlag("0");
        List<OrderVo> orders = null;
        if ("USER".equals(requestVo.getRoleKey()) || "AGENT".equals(requestVo.getRoleKey()) || "REGIMENT".equals(requestVo.getRoleKey())) {
            orders = orderMapper.selectList(requestVo);
        } else if ("MERCHANT".equals(requestVo.getRoleKey())) {
            orders = orderMapper.selectGoodsList(requestVo);
        } else if ("GROUPLEADER".equals(requestVo.getRoleKey())) {
            orders = orderMapper.selectGroupLeaderOrder(requestVo);
        } else {
            orders = orderMapper.selectFactoryOrderList(requestVo);
        }
        orders.stream().forEach(orderVo -> BeanUtils.copyProperties(this.getDetail(orderVo.getId()), orderVo));
        return orders;
    }

    @Override
    public List<OrderVo> aggregateQuery(OrderListRequestVo requestVo) {
        requestVo.setDelFlag("0");
        List<OrderVo> orders = null;
        requestVo.setAction(false);
        boolean globalQuery = StringUtils.isNotBlank(requestVo.getOutTradeNo());
        if (globalQuery || StringUtils.isNotBlank(requestVo.getWaybillId()) || StringUtils.isNotBlank(requestVo.getWaybillId())) {
            orders = orderMapper.selectList(requestVo);
        } else if ((globalQuery && CollectionUtils.isEmpty(orders)) || "MERCHANT".equals(requestVo.getRoleKey())) {
            orders = orderMapper.selectGoodsList(requestVo);
        } else if ((globalQuery && CollectionUtils.isEmpty(orders)) || StringUtils.isNotBlank(requestVo.getBarCode())){
            requestVo.setRoleKey("SUPPLIER");
            orders = orderMapper.selectFactoryOrderList(requestVo);
        }
        if (CollectionUtils.isEmpty(orders)){
            orders = new ArrayList<>();
        }
        orders.stream().forEach(orderVo -> BeanUtils.copyProperties(this.getDetail(orderVo.getId()), orderVo));
        return orders;
    }

    @Override
    public Refund orderRefund(OrderRequestVo refundRequestVo) {
        Order order = this.get(refundRequestVo.getOrderId());
        if (order == null) {
            throw new CustomException("订单不存在");
        }
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
        for (OrderProduct orderProduct : orderProductList) {
            if (StringUtils.isNotBlank(orderProduct.getWaybillId()) && StringUtils.isNotBlank(orderProduct.getDeliveryId())){
                orderProduct.setUpdateTime(new Date());
                orderProduct.setUpdateBy(refundRequestVo.getUserId());
                orderProductService.update(orderProduct);
                /*try {
                    Boolean bool = null;
                    if (DeliveryEnum.SF.toString().equals(orderProduct.getDeliveryId())) {
                        bool = logisticService.cancelSfOrder(order.getId(), orderProduct.getDeliveryId(), orderProduct.getWaybillId(), refundRequestVo.getAppid(), refundRequestVo.getSecret(), refundRequestVo.getUserId());
                    } else {
                        bool = logisticService.cancelOrder(order.getId(),orderProduct.getDeliveryId(), orderProduct.getWaybillId());
                    }
                }catch (Exception e){
                }*/
            }
        }
        String outRefundNo = this.generateOrderOutTradeNo(order.getMobile(), System.currentTimeMillis());
        String payerId = order.getPayerId();
        User user = userService.get(payerId);
        Refund refund = wechatService.refund(user.getAppid(), order.getOrderType() == 1 ? wxConfig.getSubMchid() : wxConfig.getLaundryMerchant().getMchid(), order.getOutTradeNo(), outRefundNo, order.getTotalPrice(), order.getTotalPrice());
        if (refund != null) {
            order.setRefundTime(new Date());
            order.setOutRefundNo(refund.getOutRefundNo());
            order.setRefundUserId(refundRequestVo.getUserId());
            if ("PROCESSING".equalsIgnoreCase(refund.getStatus().toString())) {
                order.setRefundStatus(1);
            }
            if ("SUCCESS".equalsIgnoreCase(refund.getStatus().toString())) {
                order.setRefundStatus(2);
            }
            if ("ABNORMAL".equalsIgnoreCase(refund.getStatus().toString())) {
                order.setRefundStatus(3);
            }
            if ("CLOSED".equalsIgnoreCase(refund.getStatus().toString())) {
                order.setRefundStatus(4);
            }
        }
        order.setOrderStatus(3);
        this.update(order);
        return refund;
    }

    @Override
    public OrderVo getDetail(String orderId) {
        Order order = this.get(orderId);
        if (order == null) {
            order = this.orderMapper.selectByOrderCode(orderId);
        }
        if (order == null) {
            order = this.orderMapper.selectByOutTradeNo(orderId);
        }
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
        return this.getDetail(order.getId(), orderProductList);

    }

    @Override
    public OrderVo getDetail(String orderId, List<OrderProduct> orderProductList) {
        Order order = this.get(orderId);
        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(order, orderVo);
//        User regiment = userService.get(order.getRegimentId());
        Dept dept = deptService.get(order.getDeptId());
        if (order.getOrderType() == 1) {
            if (!CollectionUtils.isEmpty(orderProductList)) {
                if (StringUtils.isBlank(order.getPickUpType())) {
                    order.setPickUpType(orderProductList.get(0).getPickUpType());
                }
                orderVo.setWaybillNo(orderProductList.get(0).getWaybillId());
                orderVo.setOrderTimeFormat(CommonUtils.format(order.getLastUpdateTime()));
                for (OrderProduct product : orderProductList) {
                    List<OrderAddress> addressList = orderAddressService.getAddressList(order.getId());
                    product.setRecMan(addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().get());
                    product.setSendMan(addressList.stream().filter(orderAddress -> orderAddress.getType() == 1).findFirst().get());
                }
            }
        }
        if (order.getOrderType() == 2) {
            for (OrderProduct product : orderProductList) {
                SysCartItem cartItem = cartItemService.get(product.getCartItemId());
                SysProduct cartProduct = productService.get(cartItem.getProductId());
                if (cartProduct != null) {
                    product.setName(cartProduct.getName());
                    product.setCategoryId(cartProduct.getCategoryId());
                    product.setTypeId(cartProduct.getTypeId());
                    product.setSketch(cartProduct.getSketch());
                    product.setIntro(cartProduct.getIntro());
                    product.setKeywords(cartProduct.getKeywords());
                    product.setTags(cartProduct.getTags());
                    product.setMarketPrice(cartProduct.getMarketPrice());
                    product.setPictureUrl(cartProduct.getPictureUrl());
                }
                product.setQuantity(cartItem.getQuantity());
                product.setPricePerUnit(cartItem.getPricePerUnit());
                BigDecimal totalPrice = cartItem.getTotalPrice();
                BigDecimal bigDecimal = cartItem.getServePrice() == null ? BigDecimal.ZERO : cartItem.getServePrice();
                product.setTotalPrice(totalPrice.add(bigDecimal).setScale(2, RoundingMode.HALF_UP));
                product.setSelected(cartItem.getSelected());
                product.setItemCode(generateOrderCode());
                List<Long> colorIds = JSONArray.parseArray(cartItem.getColorId(), Long.class);
                product.setColorIds(colorIds);
                product.setColorOptions(productOptionService.getList(colorIds));
                List<Long> serveIds = JSONArray.parseArray(cartItem.getServeId(), Long.class);
                product.setServeIds(serveIds);
                product.setServeOptions(productOptionService.getList(serveIds));
                List<Long> defectIds = JSONArray.parseArray(cartItem.getDefectId(), Long.class);
                product.setDefectIds(defectIds);
                product.setDefectOptions(productOptionService.getList(defectIds));
                List<Long> affixIds = JSONArray.parseArray(cartItem.getAffixId(), Long.class);
                product.setAffixIds(affixIds);
                product.setAffixOptions(productOptionService.getList(affixIds));
                product.setRemark(cartItem.getRemark());
                User user = userService.get(order.getUserId());
                orderVo.setUserName(user.getName());
                orderVo.setUserAvatar(user.getAvatar());
                product.setImg(cartItem.getImg());
            }
            List<OrderAddress> addressList = orderAddressService.getAddressList(order.getId());
            if (addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().isPresent()) {
                orderVo.setUserAddress(addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().get());
            }
            if (addressList.stream().filter(orderAddress -> orderAddress.getType() == 3).findFirst().isPresent()) {
                orderVo.setDeptAddress(addressList.stream().filter(orderAddress -> orderAddress.getType() == 3).findFirst().get());
            }
            orderProductList.sort(Comparator.comparing(OrderProduct::getId));
            orderVo.setNum(orderProductList.size());
            orderVo.setLatestEventType(orderLogisticsService.getLatestOrderEventType(order.getId()));
            orderVo.setOrderTimeFormat(CommonUtils.format(order.getLastUpdateTime()));
        }
        if (order.getOrderType() == 3) {
            for (OrderProduct orderProduct : orderProductList) {
                RegimentAssist assist = regimentAssistService.get(orderProduct.getAssistId());
                orderProduct.setName(assist.getName());
                orderProduct.setSketch(assist.getSketch());
                orderProduct.setIntro(assist.getIntro());
                orderProduct.setMarketPrice(assist.getPrice());
                orderProduct.setPrice(assist.getPrice());
                orderProduct.setTotalPrice(assist.getPrice());
                orderProduct.setPictureUrl(assist.getAttachUrl());
            }
            orderVo.setOrderTimeFormat(CommonUtils.format(order.getLastUpdateTime()));
            List<OrderAddress> addressList = orderAddressService.getAddressList(order.getId());
            if (addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().isPresent()) {
                orderVo.setUserAddress(addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().get());
            }
        }
        if (order.getOrderType() == 4) {
            List<OrderAddress> addressList = orderAddressService.getAddressList(order.getId());
            for (OrderProduct orderProduct : orderProductList) {
                Goods goods = goodsService.get(orderProduct.getProductId());
//                GoodsCartItem cartItem = goodsCartItemMapper.selectByPrimaryKey(orderProduct.getCartItemId());
                if (goods != null) {
                    orderProduct.setName(goods.getName());
                    orderProduct.setSketch(goods.getSketch());
                    orderProduct.setIntro(goods.getIntro());
                    orderProduct.setMarketPrice(goods.getPrice());
                    orderProduct.setPictureUrl(goods.getAttachUrl());
                }
                if (addressList.stream().filter(orderAddress -> orderAddress.getType() == 4 && orderAddress.getOrderProductId() != null && orderAddress.getOrderProductId().equals(orderProduct.getId())).findFirst().isPresent()) {
                    orderProduct.setMerchantAddress(addressList.stream().filter(orderAddress -> orderAddress.getType() == 4).findFirst().get());
                }
            }
            orderVo.setOrderTimeFormat(CommonUtils.format(order.getLastUpdateTime()));
            if (addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().isPresent()) {
                orderVo.setUserAddress(addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().get());
            }
            if (addressList.stream().filter(orderAddress -> orderAddress.getType() == 3).findFirst().isPresent()) {
                orderVo.setDeptAddress(addressList.stream().filter(orderAddress -> orderAddress.getType() == 3).findFirst().get());
            }
            orderProductList.sort(Comparator.comparing(OrderProduct::getId));
        }
        orderVo.setProductList(orderProductList);
//        orderVo.setRegimentName(regiment.getName());
        orderVo.setDeptAvatar(dept.getAvatar());
        orderVo.setDeptName(dept.getDeptName());
        User user = userService.get(order.getUserId());
        orderVo.setUserAvatar(user.getAvatar());
        orderVo.setUserName(user.getName());
        orderVo.setUserPhone(user.getMobile());
        return orderVo;
    }

    @Override
    public List<OrderProduct> getWaybillNo(String orderId, String userId) {
        Order order = this.get(orderId);
        if (order == null) {
            throw new CustomException("订单不存在");
        }
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
        if (orderProductList.stream().filter(orderProduct -> StringUtils.isBlank(orderProduct.getWaybillId())).findAny().isPresent()) {
            return logisticService.createOrder(order.getId());
        } else {
            return orderProductList;
        }
    }

    @Override
    public Object cancel(OrderRequestVo orderRequestVo) {
        if (StringUtils.isBlank(orderRequestVo.getOrderId()) || StringUtils.isBlank(orderRequestVo.getUserId())) {
            throw new CustomException("参数错误");
        }
        Order order = this.get(orderRequestVo.getOrderId());
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
        if (order.getOrderType() == 1) {
            OrderProduct product = orderProductList.get(0);
            String deliveryId = product.getDeliveryId();
            String waybillId = product.getWaybillId();
            if (StringUtils.isBlank(waybillId)) {
                order.setOrderStatus(3);
                this.orderRefund(orderRequestVo);
            } else {
                if (DeliveryEnum.SF.toString().equals(product.getDeliveryId())){
                    Boolean success = logisticService.cancelSfOrder(order.getId(), deliveryId, waybillId, orderRequestVo.getAppid(), orderRequestVo.getSecret(), orderRequestVo.getUserId());
                    if (success){
                        product.setUpdateTime(new Date());
                        product.setUpdateBy(orderRequestVo.getUserId());
                        orderProductService.update(product);
                        if (order.getPayStatus() != null && order.getPayStatus() == 1) {
                            order.setOrderStatus(3);
                            this.orderRefund(orderRequestVo);
                        }
                    }
                } else {
                    List<OrderLogisticStep> logistic = logisticService.queryLogistic(order.getId(), product.getDeliveryId(), product.getWaybillId(), orderRequestVo.getAppid(), orderRequestVo.getSecret(), orderRequestVo.getUserId());
                    boolean hasLogistics = !CollectionUtils.isEmpty(logistic);
                    if (hasLogistics) {
                        boolean isJD = DeliveryEnum.JD.toString().equals(deliveryId);
                        if (!isJD || (logistic.size() >= 2 &&
                                logistic.stream().noneMatch(v -> "200052".equalsIgnoreCase(v.getStatus())))) {
                            throw new CustomException("检测到单号【" + product.getWaybillId() + "】已发生物流轨迹无法取消");
                        }
                    }
                    product.setUpdateTime(new Date());
                    product.setUpdateBy(orderRequestVo.getUserId());
                    orderProductService.update(product);
                    if (order.getPayStatus() != null && order.getPayStatus() == 1) {
                        order.setOrderStatus(3);
                        this.orderRefund(orderRequestVo);
                    }
                }
            }
        }
        if (order.getOrderType() == 2) {
            if (order.getPayStatus() == 1) {
                Integer latestOrderEventType = orderLogisticsService.getLatestOrderEventType(order.getId());
                if (latestOrderEventType != null && latestOrderEventType != 0 && latestOrderEventType > 1) {
                    throw new CustomException("该订单已不可退款");
                }
                return this.orderRefund(orderRequestVo);
            } else {
                order.setDelFlag("0");
                order.setOrderStatus(5);
                order.setUpdateBy(orderRequestVo.getUserId());
                update(order);
            }
        }
        if (order.getOrderType() == 3) {
            if (order.getPayStatus() == 1) {
                Refund refund = this.orderRefund(orderRequestVo);
                if (Status.SUCCESS.equals(refund.getStatus()) || Status.PROCESSING.equals(refund.getStatus())) {
                    RegimentAssist assist = regimentAssistService.get(orderProductList.get(0).getAssistId());
                    assist.setStatus("0");
                    regimentAssistService.update(assist);
                }
                return refund;
            } else {
                order.setDelFlag("0");
                order.setOrderStatus(5);
                order.setUpdateBy(orderRequestVo.getUserId());
                update(order);
            }
        }
        if (order.getOrderType() == 4) {
            if (order.getPayStatus() == 1) {
                for (OrderProduct orderProduct : orderProductList) {
                    if (StringUtils.isNotBlank(orderProduct.getWaybillId()) && StringUtils.isNotBlank(orderProduct.getDeliveryId())){
                        List<OrderLogisticStep> logistic = logisticService.queryLogistic(order.getId(), orderProduct.getDeliveryId(), orderProduct.getWaybillId(), orderRequestVo.getAppid(), orderRequestVo.getSecret(), orderRequestVo.getUserId());
                        if (!CollectionUtils.isEmpty(logistic)){
                            throw new CustomException("检测到单号【" + orderProduct.getWaybillId() + "】已发生物流轨迹无法取消");
                        }
                        Boolean bool = null;
                        if (DeliveryEnum.SF.toString().equals(orderProduct.getDeliveryId())) {
                            bool = logisticService.cancelSfOrder(order.getId(), orderProduct.getDeliveryId(), orderProduct.getWaybillId(), orderRequestVo.getAppid(), orderRequestVo.getSecret(), orderRequestVo.getUserId());
                        } else {
                            bool = logisticService.cancelOrder(order.getId(),orderProduct.getDeliveryId(), orderProduct.getWaybillId());
                        }
                        if (bool != null && bool) {
                            orderProduct.setUpdateTime(new Date());
                            orderProduct.setUpdateBy(orderRequestVo.getUserId());
                            orderProductService.update(orderProduct);
                        } else {
                            throw new CustomException("取消失败");
                        }
                    }
                }
                Refund refund = this.orderRefund(orderRequestVo);
                if (Status.SUCCESS.equals(refund.getStatus()) || Status.PROCESSING.equals(refund.getStatus())) {
                    for (OrderProduct orderProduct : orderProductList) {
                        /*GoodsCartItem cartItem = goodsCartItemMapper.selectByPrimaryKey(orderProduct.getCartItemId());
                        GoodsCart cart = goodsCartMapper.selectByPrimaryKey(cartItem.getGoodsCartId());
                        if (cartItem != null && cart != null){
                            cart.setStatus("0");
                            goodsCartMapper.updateByPrimaryKey(cart);
                            cartItem.setStatus("0");
                            cartItem.setUpdateTime(new Date());
                            cartItem.setLastUpdateTime(new Date());
                            goods.setStock(goods.getStock() + cartItem.getQuantity());
                            goodsCartItemMapper.updateByPrimaryKey(cartItem);
                            }*/
                        Goods goods = goodsService.get(orderProduct.getProductId());
                        goods.setStock(goods.getStock() + 1);
                        goodsService.update(goods);
                    }
                }
                return refund;
            } else {
                order.setDelFlag("0");
                order.setOrderStatus(5);
                order.setUpdateBy(orderRequestVo.getUserId());
                update(order);
            }
        }
        return null;
    }

    @Override
    public Object queryLogistic(String orderId, String outTradeNo, String userId, String appid, String secret) {
        List<OrderLogisticsVo> orderLogistics = new ArrayList<>(4);
        Order order = StringUtils.isNotBlank(orderId) ? this.get(orderId) : orderMapper.selectByOutTradeNo(outTradeNo);
        if (order.getOrderType() == 1) {
            List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
            for (OrderProduct orderProduct : orderProductList) {
                OrderLogisticsVo logisticsVo = new OrderLogisticsVo();
                String deliveryId = orderProduct.getDeliveryId();
                String waybillId = orderProduct.getWaybillId();
                if (StringUtils.isBlank(waybillId)) {
                    throw new CustomException("请先获取电子面单");
                }
                List<OrderLogisticStep> orderLogisticStepList = new ArrayList<>();
                orderLogisticStepList.addAll(logisticService.queryLogistic(order.getId(), deliveryId, waybillId, appid, secret, userId));
                Collections.reverse(orderLogisticStepList);
                logisticsVo.setWaybillId(orderProduct.getWaybillId());
                logisticsVo.setPath(orderLogisticStepList);
                orderLogistics.add(logisticsVo);
            }
        }
        if (order.getOrderType() == 2) {
            List<SysOrderLogistics> logistics = orderLogisticsService.getList(order.getId());
            Map<String, List<SysOrderLogistics>> orderProductGroup = logistics.stream().collect(Collectors.groupingBy(ol -> ol.getOrderProductId()));
            for (Map.Entry<String, List<SysOrderLogistics>> entry : orderProductGroup.entrySet()) {
                List<OrderLogisticStep> orderLogisticStepList = new ArrayList<>();
                for (SysOrderLogistics logistic : entry.getValue()) {
                    OrderLogisticStep orderLogisticStep = new OrderLogisticStep();
                    orderLogisticStep.setSigner(logistic.getSigner());
                    orderLogisticStep.setCarNo(logistic.getCarNo());
                    orderLogisticStep.setDescription(logistic.getDescription());
                    orderLogisticStep.setPhone(logistic.getUserPhone());
                    orderLogisticStep.setName(logistic.getActorName());
                    orderLogisticStep.setStationName(logistic.getStationName());
                    orderLogisticStep.setTime(DateUtil.format(logistic.getTime(), "yyyy-MM-dd HH:mm:ss"));
                    orderLogisticStepList.add(orderLogisticStep);
                }
                OrderProduct orderProduct = orderProductService.get(entry.getKey());
                OrderLogisticsVo logisticsVo = new OrderLogisticsVo();
                logisticsVo.setWaybillId(orderProduct.getCode());
                logisticsVo.setPath(orderLogisticStepList);
                orderLogistics.add(logisticsVo);
            }
        }
        return orderLogistics;
    }

    @Override
    public Object remove(String orderId, String userId) {
        Order order = this.get(orderId);
        if (order == null) {
            throw new CustomException("订单不存在");
        }
        if (order.getPayStatus() != null && order.getPayStatus() == 1) {
            throw new CustomException("此订单已支付暂时不可删除");
        }
        order.setDelFlag("1");
        order.setUpdateBy(userId);
        order.setUpdateTime(new Date());
        return this.update(order);
    }

    @Override
    public Object incrPrintTimes(OrderRequestVo orderRequestVo) {
        Order order = this.get(orderRequestVo.getOrderId());
        if (order == null) {
            throw new CustomException("订单不存在");
        }
        if (order.getOrderType() != 4 && (orderRequestVo.getOrderProductId() == null || order.getOrderType() == 1)) {
            int printTimes = order.getPrintTimes() == null ? 0 : order.getPrintTimes();
            order.setPrintTimes(printTimes + 1);
            order.setLastPrintTime(new Date());
            order.setUpdateBy(orderRequestVo.getUserId());
            order.setUpdateTime(new Date());
            if (order.getOrderType() != null && order.getOrderType() == 2 && orderRequestVo.getUserId().equals(order.getRegimentId())) {
                List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
                for (OrderProduct orderProduct : orderProductList) {
                    userOrderEventService.addInitEvent(orderRequestVo.getUserId(), orderRequestVo.getDeptId(), order.getId(), orderProduct.getId());
                    orderLogisticsService.addOrderLogistics(order.getId(), orderProduct.getId(), 1, orderRequestVo.getUserId(), orderRequestVo.getDeptId(), true);
                }
            }
            return orderMapper.updateByPrimaryKey(order);
        } else if (order.getOrderType() == 4) {
            for (String orderProductId : orderRequestVo.getOrderProductIds()) {
                OrderProduct orderProduct = orderProductService.get(orderProductId);
                int printTimes = orderProduct.getPrintTimes() == null ? 0 : orderProduct.getPrintTimes();
                orderProduct.setPrintTimes(printTimes + 1);
                orderProduct.setLastUpdateTime(new Date());
                orderProduct.setUpdateBy(orderRequestVo.getUserId());
                orderProduct.setUpdateTime(new Date());
                orderProductService.update(orderProduct);
            }
            int printTimes = order.getPrintTimes() == null ? 0 : order.getPrintTimes();
            order.setPrintTimes(printTimes + 1);
            order.setLastPrintTime(new Date());
            order.setUpdateBy(orderRequestVo.getUserId());
            order.setUpdateTime(new Date());
            return orderMapper.updateByPrimaryKey(order);
        } else {
            OrderProduct orderProduct = orderProductService.get(orderRequestVo.getOrderProductId());
            int printTimes = orderProduct.getPrintTimes() == null ? 0 : orderProduct.getPrintTimes();
            orderProduct.setPrintTimes(printTimes + 1);
            orderProduct.setLastUpdateTime(new Date());
            orderProduct.setUpdateBy(orderRequestVo.getUserId());
            orderProduct.setUpdateTime(new Date());
            return orderProductService.update(orderProduct);
        }
    }

    @Override
    public List<OrderPaymentSummary> paymentList(String startDate, String endDate, String userId, Long deptId, Integer checkType) {
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            startDate = LocalDate.now().format(dateTimeFormatter);
            endDate = DateUtil.offsetDay(new Date(), -7).toLocalDateTime().format(dateTimeFormatter);
        }
        List<OrderPaymentSummary> list = orderMapper.selectOrderPaymentList(startDate, endDate, userId, deptId, checkType);
        for (OrderPaymentSummary orderPaymentSummary : list) {
            orderPaymentSummary.setTotal(orderPaymentSummary.getPaymentTotal().subtract(orderPaymentSummary.getRefundTotal()));
        }
        return list;
    }

    @Override
    public List<OrderPayment> paymentDetailList(String startDate, String endDate, Integer type, String userId, Long subDeptId, Long deptId, Integer checkType) {
        List<OrderPayment> payments = orderMapper.selectOrderPaymentDetailList(startDate, endDate, type, userId, deptId, checkType == null? 1:checkType);
        payments.stream().forEach(orderPayment -> {
            if (orderPayment.getRefundStatus() != null && orderPayment.getRefundStatus() == 2) {
                if (type == 2) {
                    orderPayment.setNote("退款成功");
                    orderPayment.setAmount(orderPayment.getAmount().negate());
                } else {
                    orderPayment.setNote("已全额退款");
                }
            }
            if ("1".equalsIgnoreCase(orderPayment.getOrderType())) {
                List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderPayment.getOrderId());
                if (!CollectionUtils.isEmpty(orderProductList)) {
                    orderPayment.setBusinessDescription(orderProductList.get(0).getItemType());
                }
                orderPayment.setName(orderPayment.getName() + (StringUtils.isNotBlank(orderPayment.getRegimentName()) ? "-" + orderPayment.getRegimentName() : ""));
            }
            if ("2".equalsIgnoreCase(orderPayment.getOrderType())) {
                List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderPayment.getOrderId());
                if (!CollectionUtils.isEmpty(orderProductList)) {
                    StringBuilder businessDesc = new StringBuilder();
                    for (int i = 0; i < orderProductList.size(); i++) {
                        OrderProduct orderProduct = orderProductList.get(i);
                        SysCartItem cartItem = cartItemService.get(orderProduct.getCartItemId());
                        SysProduct product = productService.get(orderProduct.getProductId());
                        // 拼接商品信息
                        businessDesc.append((product.getKeywords() == null ? "" : product.getKeywords()))
                                .append(product.getName())
                                .append("   *   ")
                                .append(cartItem.getQuantity());
                        // 如果不是最后一个商品，添加换行符
                        if (i != orderProductList.size() - 1) {
                            businessDesc.append("\n");
                        }
                    }
                    // 将拼接的内容用双引号包裹，确保换行符在CSV中生效
                    String businessDescription = "\"" + businessDesc.toString().replace("\"", "\"\"") + "\"";
                    orderPayment.setBusinessDescription(businessDescription);
                    if (checkType != 2){
                        orderPayment.setName(orderPayment.getName() + (StringUtils.isNotBlank(orderPayment.getRegimentName()) ? "-" + orderPayment.getRegimentName() : ""));
                    }
                }
            }
            if ("3".equals(orderPayment.getOrderType())) {
                List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderPayment.getOrderId());
                if (!CollectionUtils.isEmpty(orderProductList)) {
                    if (!CollectionUtils.isEmpty(orderProductList)) {
                        StringBuilder businessDesc = new StringBuilder();
                        for (int i = 0; i < orderProductList.size(); i++) {
                            SysProduct product = productService.get(orderProductList.get(i).getProductId());
                            // 拼接商品信息
                            businessDesc.append(product.getName());
                            // 如果不是最后一个商品，添加换行符
                            if (i != orderProductList.size() - 1) {
                                businessDesc.append("\n");
                            }
                        }
                        // 将拼接的内容用双引号包裹，确保换行符在CSV中生效
                        String businessDescription = "\"" + businessDesc.toString().replace("\"", "\"\"") + "\"";
                        orderPayment.setBusinessDescription(businessDescription);
                    }
//                    orderPayment.setBusinessDescription(StringUtils.join(orderProductList.stream().map(v -> productService.get(v.getProductId()).getName()).collect(Collectors.toList()), ","));
                }
            }
            if ("4".equals(orderPayment.getOrderType())) {
                List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderPayment.getOrderId());
                if (!CollectionUtils.isEmpty(orderProductList)) {
                    StringBuilder businessDesc = new StringBuilder();
                    for (int i = 0; i < orderProductList.size(); i++) {
                        Goods goods = goodsService.get(orderProductList.get(i).getProductId());
                        // 拼接商品信息
                        businessDesc.append(goods.getName());
                        // 如果不是最后一个商品，添加换行符
                        if (i != orderProductList.size() - 1) {
                            businessDesc.append("\n");
                        }
                    }
                    // 将拼接的内容用双引号包裹，确保换行符在CSV中生效
                    String businessDescription = "\"" + businessDesc.toString().replace("\"", "\"\"") + "\"";
                    orderPayment.setBusinessDescription(businessDescription);
                }
            }
        });
        return payments;
    }

    @Override
    public Order createCartOrder(List<SysCartItem> itemList, String userId, String regimentId, String appid, String mobile, String userName, Long deptId) {
        if (!isValidPhoneNumber(mobile)) {
            throw new CustomException("不正确的手机号");
        }
        User user = userService.get(userId);
        Order order = new Order();
        order.setId(IdUtil.getSnowflakeNextIdStr());
        order.setOrderTime(new Date());
        order.setOrderCode(generateShortCode());
        order.setOutTradeNo(this.generateOrderOutTradeNo(mobile, System.currentTimeMillis()));
        order.setMobile(mobile);
        order.setAppid(appid);
        order.setProductCategory(2);
        order.setRegimentId(regimentId);
        order.setUserId(userId);
        order.setDeptId(deptId);
        order.setPayStatus(0);
        order.setOrderStatus(1);
        order.setTotalPrice(BigDecimal.ZERO);
        order.setCreateBy(userId);
        order.setOrderType(2);
        order.setCreateTime(new Date());
        order.setLastUpdateTime(new Date());
        List<OrderProduct> orderProducts = new ArrayList<>(itemList.size());
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (SysCartItem cartItem : itemList) {
            OrderProduct orderProduct = new OrderProduct();
            long id = IdUtil.getSnowflakeNextId();
            orderProduct.setId(String.valueOf(id));
//            orderProduct.setCode(convertToFixedLengthHash(id));
            orderProduct.setOrderId(order.getId());
            orderProduct.setUserId(userId);
            orderProduct.setCartItemId(cartItem.getId());
            orderProduct.setProductId(cartItem.getProductId());
            BigDecimal price = cartItem.getTotalPrice();
            orderProduct.setTotalPrice(price);
            orderProduct.setPickUpPrice(BigDecimal.ZERO);
            orderProduct.setLastUpdateTime(new Date());
            orderProduct.setCreateTime(new Date());
            orderProduct.setStatus("0");
            orderProduct.setDelFlag("0");
            orderProducts.add(orderProduct);
            totalPrice = totalPrice.add(price);
            orderProductService.save(orderProduct);
        }
        order.setTotalPrice(new BigDecimal("100").multiply(totalPrice));
//        User regiment = userService.get(regimentId);
        Dept dept = deptService.get(deptId);
        OrderAddress regimentOrderAddress = new OrderAddress();
        OrderAddress receiverOrderAddress = new OrderAddress();
        receiverOrderAddress.setMobile(mobile);
        receiverOrderAddress.setOrderId(order.getId());
        receiverOrderAddress.setName(userName);
        receiverOrderAddress.setType(2);
        receiverOrderAddress.setLastUpdateTime(new Date());
        receiverOrderAddress.setCreateBy(order.getUserId());
        receiverOrderAddress.setCreateTime(new Date());
        receiverOrderAddress.setStatus("0");
        receiverOrderAddress.setDelFlag("0");
        orderAddressService.save(receiverOrderAddress);
        regimentOrderAddress.setMobile(dept.getMobile());
        regimentOrderAddress.setOrderId(order.getId());
        regimentOrderAddress.setUserId(order.getUserId());
        regimentOrderAddress.setProvince(dept.getProvince());
        regimentOrderAddress.setCity(dept.getCity());
        regimentOrderAddress.setArea(dept.getArea());
        regimentOrderAddress.setAddress(dept.getAddress());
        regimentOrderAddress.setName(dept.getDeptName());
        regimentOrderAddress.setType(3);
        regimentOrderAddress.setLastUpdateTime(new Date());
        regimentOrderAddress.setCreateBy(order.getUserId());
        regimentOrderAddress.setCreateTime(new Date());
        regimentOrderAddress.setStatus("0");
        regimentOrderAddress.setDelFlag("0");
        orderAddressService.save(regimentOrderAddress);
        return this.create(order);
    }

    @Override
    public boolean logisticsEventUpdate(String orderId, String orderProductId, String userId, Long deptId) {
        List<Role> roleList = userRoleService.getRoleList(userId, deptId);
        Order order = orderMapper.selectByPrimaryKey(orderId);
        if (order == null) {
            throw new CustomException("数据异常");
        }
        Role role = roleList.stream().filter(e -> "REGIMENT".equals(e.getRoleKey())
                || "SUPPLIER".equals(e.getRoleKey())
//                || "DRIVER".equals(e.getRoleKey())
                || "SCANNER".equals(e.getRoleKey())).findAny().get();
        return orderLogisticsService.addOrderLogistics(order.getId(), orderProductId, orderLogisticsService.getEvent(order.getId(), orderProductId, role.getId(), userId, deptId).getType(), userId, deptId, false);
    }

    @Override
    public synchronized String generateOrderCode() {
        String date = LocalDate.now().toString();
        return String.format("%s%04d", date.replaceAll("-", ""), orderMapper.countOrder(date) + 1);
    }

    @Override
    public boolean addUserLogisticsOrder(String outTradeNo, Long roleId, String userId, Long deptId) {
    /*    Order order = orderMapper.selectByOutTradeNo(outTradeNo.toLowerCase());
        if (order != null) {
            Integer eventType = orderLogisticsService.getLatestEventType(order.getId());
            if (eventType != null && eventType >= LogisticsEventEnum.FACTORY_PICKUP.getType()) {
                throw new CustomException("此条码已失效");
            }
        }*/
        OrderProduct orderProduct = orderProductService.query(outTradeNo);
        if (orderProduct == null || StringUtils.isBlank(orderProduct.getCode())) {
            throw new CustomException("条码异常");
        }
        Order order = orderMapper.selectByPrimaryKey(orderProduct.getOrderId());
        if (order == null) {
            throw new CustomException("此单号不存在");
        }
        Role role = roleService.getRole(roleId);
        if ("REGIMENT".equals(role.getRoleKey()) && !userId.equals(order.getRegimentId())) {
            throw new CustomException("无权限");
        }
        if (!orderLogisticsService.checkExistsPreLogistics(order.getId(), orderLogisticsService.getEvent(order.getId(), orderProduct.getId(), roleId, userId, deptId).getType(), false)) {
            throw new CustomException("请勿提前扫码");
        }
        Integer eventType = orderLogisticsService.getLatestOrderProductEventType(order.getId(), orderProduct.getId());
        if (eventType != null && eventType == 4) {
            throw new CustomException("此条码已失效");
        }
        userOrderEventService.lastEvent(order.getId(), orderProduct.getId(), eventType);
        userOrderEventService.verify(role.getRoleKey(), eventType);
        userOrderEventService.verifyUniformity(deptId, eventType + 1);
        return userOrderEventService.addUserData(userId, deptId, order.getId(), orderProduct == null ? null : orderProduct.getId(), eventType + 1);
    }

    @Override
    public boolean removeDictDataLogisticsOrder(Long id, String userId, Long deptId) {
        return userOrderEventService.removeUserData(id, userId, deptId);
    }

    @Override
    public boolean submitUserDictData(String userId, Long deptId) {
        List<UserOrderEvent> dataList = userOrderEventService.getUserData(deptId, "0");
        if (CollectionUtils.isEmpty(dataList)) {
            throw new CustomException("暂无数据");
        }
        boolean bool = userOrderEventService.clear(userId, deptId);
        for (UserOrderEvent event : dataList) {
            Order order = this.get(event.getOrderId());
            if (order.getOrderStatus() == 4) {
                throw new CustomException("请先处理退款单");
            }
            this.logisticsEventUpdate(event.getOrderId(), event.getOrderProductId(), userId, deptId);
        }
        return bool;
    }

    @Override
    public List<OrderVo> eventList(String userId, String status, Integer eventType, Long deptId) {
        List<UserOrderEvent> dataList = userOrderEventService.getUserData(deptId, status, eventType);
        List<OrderVo> list = new ArrayList<>();
        for (UserOrderEvent event : dataList) {
            OrderVo detail = getDetail(event.getOrderId());
            List<OrderProduct> productList = detail.getProductList();
            Map<String, OrderProduct> orderProductMap = productList.stream().collect(Collectors.toMap(OrderProduct::getId, orderProduct -> orderProduct));
            List<OrderProduct> alreadyAddList = new ArrayList<>(productList.size());
            String orderProductId = event.getOrderProductId();
            if (StringUtils.isNotBlank(orderProductId)) {
                OrderProduct orderProduct = orderProductMap.get(orderProductId);
                alreadyAddList.add(orderProduct);
            }
            detail.setIndex(event.getCode());
            if (!CollectionUtils.isEmpty(alreadyAddList)) {
                productList = alreadyAddList;
            }
            detail.setProductList(productList);
            detail.setEventType(event.getType());
            detail.setOrderEventId(event.getId());
            list.add(detail);
        }
//        Map<String, List<UserOrderEvent>> orderIdMap = dataList.stream().collect(Collectors.groupingBy(tmpData -> tmpData.getOrderId()));
//        for (Map.Entry<String, List<UserOrderEvent>> entry : orderIdMap.entrySet()) {
//            OrderVo detail = getDetail(entry.getKey());
//            List<UserOrderEvent> tmpList = entry.getValue();
//            List<OrderProduct> productList = detail.getProductList();
//            Map<String, OrderProduct> orderProductMap = productList.stream().collect(Collectors.toMap(OrderProduct::getId, orderProduct -> orderProduct));
//            List<OrderProduct> alreadyAddList = new ArrayList<>(productList.size());
//            for (UserOrderEvent tmp : tmpList) {
//                String orderProductId = tmp.getOrderProductId();
//                if (StringUtils.isNotBlank(orderProductId)) {
//                    OrderProduct orderProduct = orderProductMap.get(orderProductId);
//                    orderProduct.setIndex(tmp.getCode());
//                    alreadyAddList.add(orderProduct);
//                } else {
//                    detail.setIndex(tmp.getCode());
//                }
//            }
//            if (!CollectionUtils.isEmpty(alreadyAddList)) {
//                productList = alreadyAddList;
//            }
//            detail.setProductList(productList);
//            list.add(detail);
//        }
        return list;
    }

    @Override
    public Object findNonLogisticsOrderList(OrderRequestVo body) {
        List<Order> data = orderMapper.selectNonLogisticsOrderList(body.getKeyword());
        List<OrderVo> orders = new ArrayList<>();
        data.stream().forEach(order -> orders.add(getDetail(order.getId())));
        return orders;
    }

    @Override
    public List<UserEventStatistic> userOrderEventCount(String userId, Long deptId) {
        return userOrderEventService.statistic(userId, deptId);
    }

    @Override
    public String generateShortCode() {
        StringBuilder codeBuilder = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < CODE_NUMBER_LENGTH; i++) {
            int randomIndex = random.nextInt(UPPER_CASE_ALPHABETS.length());
            char randomChar = UPPER_CASE_ALPHABETS.charAt(randomIndex);
            codeBuilder.append(randomChar);
        }
        String code = codeBuilder.toString();
        if (orderMapper.selectByOrderCode(code) == null) {
            return code;
        }
        return generateShortCode();
    }

    @Override
    public Order getByCode(String orderCode) {
        return orderMapper.selectByOrderCode(orderCode);
    }

    @Override
    public OrderBill findByWaybillId(String waybillid) {
        return orderMapper.selectByWaybillId(waybillid);
    }

    @Override
    public Order createCartOrder(String userId, UserAddress receiverAddress, String appid, String mobile, Date pickUpDate, String pickUpRange, String orderImg, String remark, Long deptId) {
        if (!isValidPhoneNumber(mobile)) {
            throw new CustomException("不正确的手机号");
        }
        User user = userService.get(userId);
        User regiment = userService.get(user.getRegimentId());
        Dept dept = deptService.get(user.getDeptId());
        if (dept == null) {
            throw new CustomException("请完成选择服务站点");
        }
        Order order = new Order();
        order.setId(IdUtil.getSnowflakeNextIdStr());
        order.setOrderTime(new Date());
        order.setOrderCode(generateShortCode());
        order.setOutTradeNo(this.generateOrderOutTradeNo(mobile, System.currentTimeMillis()));
        order.setMobile(mobile);
        order.setAppid(appid);
        order.setProductCategory(2);
//        order.setRegimentId(user.getRegimentId());
        order.setPickUpDate(pickUpDate);
        order.setPickUpRange(pickUpRange);
        order.setOrderImg(orderImg);
        order.setRemark(remark);
        order.setUserId(userId);
        order.setDeptId(deptId);
        order.setPayStatus(0);
        order.setOrderStatus(1);
        order.setTotalPrice(BigDecimal.ZERO);
        order.setCreateBy(userId);
        order.setOrderType(2);
        order.setCreateTime(new Date());
        order.setLastUpdateTime(new Date());
        BigDecimal totalPrice = BigDecimal.ZERO;
        order.setTotalPrice(totalPrice);
        OrderAddress receiverOrderAddress = new OrderAddress();
        receiverOrderAddress.setCountry(receiverAddress.getCompany());
        receiverOrderAddress.setProvince(receiverAddress.getProvince());
        receiverOrderAddress.setCity(receiverAddress.getCity());
        receiverOrderAddress.setArea(receiverAddress.getArea());
        receiverOrderAddress.setTown(receiverAddress.getTown());
        receiverOrderAddress.setAddress(receiverAddress.getAddress());
        receiverOrderAddress.setMobile(receiverAddress.getMobile());
        receiverOrderAddress.setOrderId(order.getId());
        receiverOrderAddress.setName(receiverAddress.getName());
        receiverOrderAddress.setType(2);
        receiverOrderAddress.setLastUpdateTime(new Date());
        receiverOrderAddress.setCreateBy(order.getUserId());
        receiverOrderAddress.setCreateTime(new Date());
        receiverOrderAddress.setStatus("0");
        receiverOrderAddress.setDelFlag("0");
        orderAddressService.save(receiverOrderAddress);
        OrderAddress deptOrderAddress = new OrderAddress();
        deptOrderAddress.setMobile(dept.getMobile());
        deptOrderAddress.setOrderId(order.getId());
        deptOrderAddress.setUserId(order.getUserId());
        deptOrderAddress.setProvince(dept.getProvince());
        deptOrderAddress.setCity(dept.getCity());
        deptOrderAddress.setArea(dept.getArea());
        deptOrderAddress.setAddress(dept.getAddress());
        deptOrderAddress.setName(dept.getDeptName());
        deptOrderAddress.setType(3);
        deptOrderAddress.setLastUpdateTime(new Date());
        deptOrderAddress.setCreateBy(order.getUserId());
        deptOrderAddress.setCreateTime(new Date());
        deptOrderAddress.setStatus("0");
        deptOrderAddress.setDelFlag("0");
        orderAddressService.save(deptOrderAddress);
        return this.create(order);
    }

    @Override
    public PreOrderResponseVo createAssistOrder(PreOrderVo body) {
        if (!isValidPhoneNumber(body.getMobile())) {
            throw new CustomException("不正确的手机号");
        }
        List<PreOrderProduct> productList = body.getProductList();
        PreOrderProduct preOrderProduct = productList.get(0);
        RegimentAssist assist = regimentAssistService.get(preOrderProduct.getAssistId());
        User user = userService.get(body.getUserId());
        User regiment = userService.get(user.getRegimentId());
        Order order = new Order();
        order.setId(IdUtil.getSnowflakeNextIdStr());
        order.setOrderTime(new Date());
        order.setOrderCode(generateShortCode());
        order.setOutTradeNo(this.generateOrderOutTradeNo(body.getMobile(), System.currentTimeMillis()));
        order.setMobile(body.getMobile());
        order.setAppid(body.getAppid());
        order.setProductCategory(2);
        order.setRegimentId(regiment.getId());
        order.setPickUpDate(null);
        order.setPickUpRange(null);
        order.setOrderImg(assist.getAttachUrl());
        order.setRemark(body.getRemark());
        order.setUserId(body.getUserId());
        order.setPayStatus(0);
        order.setOrderStatus(1);
        order.setTotalPrice(assist.getPrice());
        order.setCreateBy(body.getUserId());
        order.setOrderType(3);
        order.setCreateTime(new Date());
        order.setLastUpdateTime(new Date());
        order.setTotalPrice(assist.getPrice());
        OrderProduct orderProduct = new OrderProduct();
        long id = IdUtil.getSnowflakeNextId();
        orderProduct.setId(String.valueOf(id));
        orderProduct.setOrderId(order.getId());
        orderProduct.setCode(convertToFixedLengthHash(id));
        orderProduct.setUserId(body.getUserId());
        orderProduct.setAssistId(assist.getId());
        orderProduct.setPrice(assist.getPrice());
        orderProduct.setPickUpPrice(BigDecimal.ZERO);
        orderProduct.setTotalPrice(assist.getPrice());
        orderProduct.setStatus("0");
        orderProduct.setDelFlag("0");
        orderProduct.setCreateTime(new Date());
        orderProduct.setCreateBy(body.getUserId());
        UserAddress recMan = preOrderProduct.getRecMan();
        OrderAddress recManAddress = new OrderAddress();
        recManAddress.setOrderProductId(orderProduct.getId());
        recManAddress.setMobile(recMan.getMobile());
        recManAddress.setOrderId(order.getId());
        recManAddress.setUserId(order.getUserId());
        recManAddress.setProvince(recMan.getProvince());
        recManAddress.setCity(recMan.getCity());
        recManAddress.setArea(recMan.getArea());
        recManAddress.setAddress(recMan.getAddress());
        recManAddress.setName(recMan.getName());
        recManAddress.setType(2);
        recManAddress.setLastUpdateTime(new Date());
        recManAddress.setCreateBy(order.getUserId());
        recManAddress.setCreateTime(new Date());
        recManAddress.setStatus("0");
        recManAddress.setDelFlag("0");
        orderAddressService.save(recManAddress);
        assist.setStatus("1");
        regimentAssistService.update(assist);
        orderProductService.save(orderProduct);
        order = this.create(order);
        return this.pay(order.getId(), order.getUserId(), order.getAppid());
    }

    @Override
    public Object confirmOrder(String orderId, String userId) {
        Order order = this.get(orderId);
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderId);
        RegimentAssist assist = regimentAssistService.get(orderProductList.get(0).getAssistId());
        assist.setUpdateBy(userId);
        assist.setUpdateTime(new Date());
        assist.setLastUpdateTime(new Date());
        assist.setStatus("3");
        order.setOrderStatus(6);
        order.setUpdateBy(userId);
        order.setUpdateTime(new Date());
        order.setLastUpdateTime(new Date());
        regimentAssistService.update(assist);
//        profitsharingOrder(orderId);
        TransferBatchEntity transfer = transfer(orderId);
        log.info("{}", JSONObject.toJSONString(transfer));
        return this.update(order);
    }

    @Override
    public void profitsharingOrder(String orderId) {
        Order order = this.get(orderId);
        if (order.getOrderType() != 3) {
            return;
        }
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderId);
        OrderProduct orderProduct = orderProductList.get(0);
        RegimentAssist assist = regimentAssistService.get(orderProduct.getAssistId());
        List<OrderProfitsharingReceiver> receiverList = orderProfitsharingReceiverService.getProfitsharingReceiverList(orderId);
        if (CollectionUtils.isEmpty(receiverList)) {
            return;
        }
        QueryOrderAmountResponse queryOrderAmountResponse = queryProfitSharingAmounts(order.getId(), order.getTransactionId());
        if (queryOrderAmountResponse == null || queryOrderAmountResponse.getUnsplitAmount() == 0L) {
            return;
        }
        Long unsplitAmount = queryOrderAmountResponse.getUnsplitAmount();
        List<CreateOrderReceiver> receivers = new ArrayList<>();
        for (OrderProfitsharingReceiver receiver : receiverList) {
            if (ReceiverType.MERCHANT_ID.toString().equalsIgnoreCase(receiver.getType())) {
                CreateOrderReceiver orderReceiver = new CreateOrderReceiver();
                BigDecimal ratio = receiver.getRatio();
                BigDecimal amount = new BigDecimal(unsplitAmount).multiply(ratio).setScale(0, RoundingMode.HALF_UP);
                if (amount.compareTo(BigDecimal.ONE) <= 0) {
                    amount = BigDecimal.ONE;
                }
                orderReceiver.setType(receiver.getType());
                orderReceiver.setAccount(receiver.getAccount());
                orderReceiver.setName(receiver.getName());
                orderReceiver.setAmount(amount.longValue());
                orderReceiver.setDescription(assist.getName() + order.getOrderCode() + "分账");
                receivers.add(orderReceiver);
            }
        }
        CreateOrderRequest createOrderRequest = new CreateOrderRequest();
        createOrderRequest.setSubMchid(wxConfig.getLaundryMerchant().getMchid());
        createOrderRequest.setAppid(clientConfig.getAppid());
        createOrderRequest.setTransactionId(order.getTransactionId());
        createOrderRequest.setOutOrderNo("ELE_SH" + IdUtil.getSnowflakeNextId());
        createOrderRequest.setReceivers(receivers);
        createOrderRequest.setUnfreezeUnsplit(false);
        log.info("createOrder order id -> {}, param {}", orderId, com.alibaba.fastjson.JSONObject.toJSONString(createOrderRequest));
        OrdersEntity profitOrderEntity = profitsharingService.createOrder(createOrderRequest);
        log.info("createOrder response -> {}", com.alibaba.fastjson.JSONObject.toJSONString(profitOrderEntity));
        if (profitOrderEntity != null) {
            List<OrderReceiverDetail> receiverDetails = profitOrderEntity.getReceivers();
            Map<String, OrderProfitsharingReceiver> profitsharingMap = receiverList.stream().collect(Collectors.toMap(OrderProfitsharingReceiver::getAccount, Function.identity(), (key1, key2) -> key2));
            for (OrderReceiverDetail detail : receiverDetails) {
                OrderProfitsharingReceiver profitsharingReceiver = profitsharingMap.get(detail.getAccount());
                OrderProfitsharing profitsharing = new OrderProfitsharing();
                profitsharing.setOrderId(orderId);
                profitsharing.setProfitsharingReceiverId(profitsharingReceiver.getId());
                profitsharing.setRatio(profitsharingReceiver.getRatio());
                profitsharing.setTransactionId(profitOrderEntity.getTransactionId());
                profitsharing.setOutOrderNo(profitOrderEntity.getOutOrderNo());
                profitsharing.setOrderAmount(new BigDecimal(unsplitAmount));
                profitsharing.setAmount(new BigDecimal(detail.getAmount()));
                profitsharing.setFinishTime(new DateTime(detail.getFinishTime()).toDate());
                profitsharing.setState(profitOrderEntity.getState().toString());
                profitsharing.setDetailId(detail.getDetailId());
                profitsharing.setDescription(detail.getDescription());
                profitsharing.setType(detail.getType().toString());
                profitsharing.setAccount(detail.getAccount());
                profitsharing.setResult(detail.getResult().toString());
                profitsharing.setFailReason(detail.getFailReason() != null ? detail.getFailReason().toString() : null);
                profitsharing.setCreateTime(new DateTime(detail.getCreateTime()).toDate());
                orderProfitsharingService.save(profitsharing);
            }
            OrderProfitsharingReceiver profitsharingReceiver = receiverList.stream().filter(receiver -> ReceiverType.PERSONAL_OPENID.toString().equalsIgnoreCase(receiver.getType())).findAny().get();
            userProfitsharing(profitsharingReceiver, order.getTransactionId(), orderId, assist.getName() + order.getOrderCode() + "分账");
        }
    }

    private void userProfitsharing(OrderProfitsharingReceiver receiver, String transactionId, String orderId, String description) {
        QueryOrderAmountResponse orderAmountResponse = queryProfitSharingAmounts(orderId, transactionId);
        if (orderAmountResponse == null || orderAmountResponse.getUnsplitAmount() == 0L) {
            return;
        } else {
            List<CreateOrderReceiver> receiversList = new ArrayList<>();
            if (ReceiverType.PERSONAL_OPENID.toString().equalsIgnoreCase(receiver.getType())) {
                CreateOrderReceiver orderReceiver = new CreateOrderReceiver();
                BigDecimal ratio = receiver.getRatio();
                BigDecimal amount = new BigDecimal(orderAmountResponse.getUnsplitAmount()).multiply(ratio).setScale(0, RoundingMode.HALF_UP);
                if (amount.compareTo(BigDecimal.ONE) <= 0) {
                    amount = BigDecimal.ONE;
                }
                orderReceiver.setType(receiver.getType());
                orderReceiver.setAccount(receiver.getAccount());
                orderReceiver.setName(receiver.getName());
                orderReceiver.setAmount(amount.longValue());
                orderReceiver.setDescription(description);
                receiversList.add(orderReceiver);
            }
            CreateOrderRequest createOrderRequest = new CreateOrderRequest();
            createOrderRequest.setSubMchid(wxConfig.getLaundryMerchant().getMchid());
            createOrderRequest.setAppid(clientConfig.getAppid());
            createOrderRequest.setTransactionId(transactionId);
            createOrderRequest.setOutOrderNo("ELE_SH" + IdUtil.getSnowflakeNextId());
            createOrderRequest.setReceivers(receiversList);
            createOrderRequest.setUnfreezeUnsplit(false);
            log.info("createOrder order id -> {}, param {}", orderId, com.alibaba.fastjson.JSONObject.toJSONString(createOrderRequest));
            OrdersEntity profitOrderEntity = profitsharingService.createOrder(createOrderRequest);
            log.info("createOrder response -> {}", com.alibaba.fastjson.JSONObject.toJSONString(profitOrderEntity));
            if (profitOrderEntity != null) {
                List<OrderReceiverDetail> receiverDetails = profitOrderEntity.getReceivers();
                Map<String, OrderProfitsharingReceiver> profitsharingMap = Arrays.asList(receiver).stream().collect(Collectors.toMap(OrderProfitsharingReceiver::getAccount, Function.identity(), (key1, key2) -> key2));
                for (OrderReceiverDetail detail : receiverDetails) {
                    OrderProfitsharingReceiver profitsharingReceiver = profitsharingMap.get(detail.getAccount());
                    OrderProfitsharing profitsharing = new OrderProfitsharing();
                    profitsharing.setOrderId(orderId);
                    profitsharing.setProfitsharingReceiverId(profitsharingReceiver.getId());
                    profitsharing.setRatio(profitsharingReceiver.getRatio());
                    profitsharing.setTransactionId(profitOrderEntity.getTransactionId());
                    profitsharing.setOutOrderNo(profitOrderEntity.getOutOrderNo());
                    profitsharing.setOrderAmount(new BigDecimal(orderAmountResponse.getUnsplitAmount()));
                    profitsharing.setAmount(new BigDecimal(detail.getAmount()));
                    profitsharing.setFinishTime(new DateTime(detail.getFinishTime()).toDate());
                    profitsharing.setState(profitOrderEntity.getState().toString());
                    profitsharing.setDetailId(detail.getDetailId());
                    profitsharing.setDescription(detail.getDescription());
                    profitsharing.setType(detail.getType().toString());
                    profitsharing.setAccount(detail.getAccount());
                    profitsharing.setResult(detail.getResult().toString());
                    profitsharing.setFailReason(detail.getFailReason() != null ? detail.getFailReason().toString() : null);
                    profitsharing.setCreateTime(new DateTime(detail.getCreateTime()).toDate());
                    orderProfitsharingService.save(profitsharing);
                }
                userProfitsharing(receiver, transactionId, orderId, description);
            }
        }
    }

    @Override
    public void unfreeze(String orderId) {
        Order order = this.get(orderId);
        List<OrderProfitsharing> profitsharingList = orderProfitsharingService.getOrderProfitsharingList(orderId);
        Map<String, List<OrderProfitsharing>> outOrderNoMap = profitsharingList.stream().collect(Collectors.groupingBy(profit -> profit.getOutOrderNo()));
        for (Map.Entry<String, List<OrderProfitsharing>> entry : outOrderNoMap.entrySet()) {
            String outNo = entry.getKey();
            UnfreezeOrderRequest request = new UnfreezeOrderRequest();
            request.setTransactionId(order.getTransactionId());
            request.setOutOrderNo(outNo);
            log.info("unfreeze order id -> {} param - > {}", orderId, com.alibaba.fastjson.JSONObject.toJSONString(request));
            OrdersEntity ordersEntity = profitsharingService.unfreezeOrder(request);
            log.info("unfreeze result - > {}", orderId, com.alibaba.fastjson.JSONObject.toJSONString(ordersEntity));
            if (ordersEntity != null) {
            }
        }
    }

    @Override
    public void profitsharingReturn(String orderId) {
        Order order = this.get(orderId);
        List<OrderProfitsharing> profitsharingList = orderProfitsharingService.getOrderProfitsharingList(order.getId());
        if (CollectionUtils.isEmpty(profitsharingList)) {
            return;
        }
        Map<String, List<OrderProfitsharing>> outOrderNoMap = profitsharingList.stream().collect(Collectors.groupingBy(profit -> profit.getOutOrderNo()));
        for (Map.Entry<String, List<OrderProfitsharing>> entry : outOrderNoMap.entrySet()) {
            String outOrderNo = entry.getKey();
            List<OrderProfitsharing> profitsharings = entry.getValue();
            for (OrderProfitsharing profitsharing : profitsharings) {
                CreateReturnOrderRequest request = new CreateReturnOrderRequest();
                request.setOutOrderNo(outOrderNo);
                request.setOutReturnNo("ELE__R" + generateOrderCode());
                request.setReturnMchid(profitsharing.getAccount());
                request.setAmount(profitsharing.getAmount().longValue());
                request.setDescription("【" + order.getOrderCode() + "】分账回退");
                ReturnOrdersEntity returnOrder = profitsharingService.createReturnOrder(request);
                if (returnOrder != null) {
                    profitsharing.setResult(returnOrder.getResult().toString());
                    profitsharing.setUpdateTime(new DateTime(returnOrder.getCreateTime()).toDate());
                    orderProfitsharingService.update(profitsharing);
                }
            }
        }
    }

    @Override
    public List<OrderProfitsharing> queryProfitsharing(String orderId, String outOrderNo) {
        Order order = this.get(orderId);
        List<OrderProfitsharing> profitsharingList = orderProfitsharingService.getOrderProfitsharingList(order.getId(), outOrderNo);
        if (CollectionUtils.isEmpty(profitsharingList)) {
            return profitsharingList;
        }
        Map<String, List<OrderProfitsharing>> outOrderNoMap = profitsharingList.stream().collect(Collectors.groupingBy(profit -> profit.getOutOrderNo()));
        for (Map.Entry<String, List<OrderProfitsharing>> entry : outOrderNoMap.entrySet()) {
            String outNo = entry.getKey();
            List<OrderProfitsharing> profitsharings = entry.getValue();
            Map<String, OrderProfitsharing> profitsharingMap = profitsharings.stream().collect(Collectors.toMap(OrderProfitsharing::getAccount, Function.identity(), (key1, key2) -> key2));
            QueryOrderRequest request = new QueryOrderRequest();
            request.setTransactionId(order.getTransactionId());
            request.setOutOrderNo(outNo);
            log.info("findExportOrderData order id -> {} param - > {}", orderId, com.alibaba.fastjson.JSONObject.toJSONString(request));
            OrdersEntity ordersEntity = profitsharingService.queryOrder(request);
            log.info("findExportOrderData ordersEntity -> {}", com.alibaba.fastjson.JSONObject.toJSONString(ordersEntity));
            if (ordersEntity != null) {
                for (OrderReceiverDetail receiver : ordersEntity.getReceivers()) {
                    OrderProfitsharing profitsharing = profitsharingMap.get(receiver.getAccount());
                    profitsharing.setState(receiver.getResult().toString());
                    profitsharing.setResult(receiver.getResult().toString());
                    profitsharing.setFailReason(receiver.getFailReason() != null ? receiver.getFailReason().toString() : null);
                    if (receiver.getFinishTime() != null) {
                        profitsharing.setFinishTime(new DateTime(receiver.getFinishTime()).toDate());
                    }
                    profitsharing.setUpdateTime(new DateTime(receiver.getCreateTime()).toDate());
                    orderProfitsharingService.update(profitsharing);
                }
            }
        }
        return orderProfitsharingService.getOrderProfitsharingList(orderId, outOrderNo);
    }

    @Override
    public QueryOrderAmountResponse queryProfitSharingAmounts(String orderId, String transactionId) {
        QueryOrderAmountRequest queryOrderAmountRequest = new QueryOrderAmountRequest();
        queryOrderAmountRequest.setTransactionId(transactionId);
        log.info("queryProfitSharingAmounts transactionId id -> {} param - > {}", transactionId);
        QueryOrderAmountResponse response = profitsharingService.queryOrderAmount(queryOrderAmountRequest);
        log.info("query order amount response -> {}", com.alibaba.fastjson.JSONObject.toJSONString(response));
        return response;
    }

    @Override
    public TransferBatchEntity transfer(String orderId) {
        Order order = this.get(orderId);
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderId);
        OrderProduct orderProduct = orderProductList.get(0);
        RegimentAssist assist = regimentAssistService.get(orderProduct.getAssistId());
        User user = userService.get(assist.getUserId());
        CreateTransferBatchRequest transferBatchRequest = new CreateTransferBatchRequest();
        transferBatchRequest.setSpAppid(clientConfig.getAppid());
        transferBatchRequest.setSubMchid(wxConfig.getLaundryMerchant().getMchid());
        transferBatchRequest.setSubAppid(clientConfig.getAppid());
        transferBatchRequest.setOutBatchNo("T" + IdUtil.getSnowflakeNextId());
        transferBatchRequest.setBatchName(assist.getName());
        transferBatchRequest.setBatchRemark("商户转账");
        transferBatchRequest.setTotalAmount(order.getTotalPrice().longValue());
        transferBatchRequest.setTotalNum(1);
        List<TransferDetailInput> detailInputs = new ArrayList<>();
        TransferDetailInput detailInput = new TransferDetailInput();
        detailInput.setOpenid(assist.getUserId());
        detailInput.setOutDetailNo("t" + IdUtil.getSnowflakeNextId());
        detailInput.setTransferAmount(order.getTotalPrice().longValue());
        detailInput.setTransferRemark(assist.getName());
        detailInput.setUserName(user.getRealName());
        detailInputs.add(detailInput);
        transferBatchRequest.setTransferDetailList(detailInputs);
        transferBatchRequest.setAuthorizationType(AuthType.INFORMATION_AUTHORIZATION_TYPE);
        log.info("batch transfer {}", JSONObject.toJSONString(transferBatchRequest));
        TransferBatchEntity transferBatch = payrollCardService.createTransferBatch(transferBatchRequest);
        log.info("transfer result {}", JSONObject.toJSONString(transferBatch));
        return transferBatch;
    }

    @Override
    public Order createGoodsOrder(List<GoodsCartItem> itemList, String userId, String regimentId, String appid, UserAddress receiverAddress, Long deptId) {
        if (!isValidPhoneNumber(receiverAddress.getMobile())) {
            throw new CustomException("不正确的手机号");
        }
        User user = userService.get(userId);
        Order order = new Order();
        order.setId(IdUtil.getSnowflakeNextIdStr());
        order.setOrderTime(new Date());
        order.setOrderCode(generateShortCode());
        order.setOutTradeNo(this.generateOrderOutTradeNo(receiverAddress.getMobile(), System.currentTimeMillis()));
        order.setMobile(receiverAddress.getMobile());
        order.setAppid(appid);
        order.setProductCategory(2);
        order.setRegimentId(regimentId);
        order.setUserId(userId);
        order.setDeptId(deptId);
        order.setPayStatus(0);
        order.setOrderStatus(1);
        order.setTotalPrice(BigDecimal.ZERO);
        order.setCreateBy(userId);
        order.setOrderType(4);
        order.setDeliveryStatus(0);
        order.setCreateTime(new Date());
        order.setLastUpdateTime(new Date());
        List<OrderProduct> orderProducts = new ArrayList<>(itemList.size());
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (GoodsCartItem cartItem : itemList) {
            for (Integer i = 0; i < cartItem.getQuantity(); i++) {
                Goods goods = goodsService.get(cartItem.getGoodsId());
                OrderProduct orderProduct = new OrderProduct();
                long id = IdUtil.getSnowflakeNextId();
                orderProduct.setId(String.valueOf(id));
                orderProduct.setCode(convertToFixedLengthHash(id));
                orderProduct.setOrderId(order.getId());
                orderProduct.setUserId(userId);
                orderProduct.setCartItemId(cartItem.getId());
                orderProduct.setProductId(cartItem.getGoodsId());
                orderProduct.setWeight(goods.getWeight() == null ? BigDecimal.ZERO.toPlainString() : goods.getWeight().toPlainString());
                BigDecimal price = cartItem.getPricePerUnit();
                orderProduct.setTotalPrice(price);
                orderProduct.setPickUpPrice(BigDecimal.ZERO);
                orderProduct.setLastUpdateTime(new Date());
                orderProduct.setCreateTime(new Date());
                orderProduct.setStatus("0");
                orderProduct.setDelFlag("0");
                orderProducts.add(orderProduct);
                totalPrice = totalPrice.add(price);
                orderProductService.save(orderProduct);
                User merchant = userService.getUser(goods.getUserId());
                OrderAddress merchantAddress = new OrderAddress();
                merchantAddress.setMobile(merchant.getMobile());
                merchantAddress.setOrderId(order.getId());
                merchantAddress.setOrderProductId(orderProduct.getId());
                merchantAddress.setUserId(order.getUserId());
                merchantAddress.setProvince(merchant.getProvince());
                merchantAddress.setCity(merchant.getCity());
                merchantAddress.setArea(merchant.getArea());
                merchantAddress.setAddress(merchant.getAddress());
                merchantAddress.setName(merchant.getName());
                merchantAddress.setRealName(merchant.getRealName());
                merchantAddress.setRealId(merchant.getRealId());
                merchantAddress.setType(4);
                merchantAddress.setLastUpdateTime(new Date());
                merchantAddress.setCreateBy(order.getUserId());
                merchantAddress.setCreateTime(new Date());
                merchantAddress.setStatus("0");
                merchantAddress.setDelFlag("0");
                orderAddressService.save(merchantAddress);
            }
        }
        order.setTotalPrice(new BigDecimal("100").multiply(totalPrice));
        User regiment = userService.get(regimentId);
        OrderAddress regimentOrderAddress = new OrderAddress();
        OrderAddress receiverOrderAddress = new OrderAddress();
        receiverOrderAddress.setMobile(receiverAddress.getMobile());
        receiverOrderAddress.setOrderId(order.getId());
        receiverOrderAddress.setName(receiverAddress.getName());
        receiverOrderAddress.setUserId(receiverAddress.getUserId());
        receiverOrderAddress.setProvince(receiverAddress.getProvince());
        receiverOrderAddress.setCity(receiverAddress.getCity());
        receiverOrderAddress.setArea(receiverAddress.getArea());
        receiverOrderAddress.setTown(receiverAddress.getTown());
        receiverOrderAddress.setCode(receiverAddress.getCode());
        receiverOrderAddress.setAddress(receiverAddress.getAddress());
        receiverOrderAddress.setType(2);
        receiverOrderAddress.setLastUpdateTime(new Date());
        receiverOrderAddress.setCreateBy(order.getUserId());
        receiverOrderAddress.setCreateTime(new Date());
        receiverOrderAddress.setStatus("0");
        receiverOrderAddress.setDelFlag("0");
        orderAddressService.save(receiverOrderAddress);
        regimentOrderAddress.setMobile(regiment.getMobile());
        regimentOrderAddress.setOrderId(order.getId());
        regimentOrderAddress.setUserId(order.getUserId());
        regimentOrderAddress.setProvince(regiment.getProvince());
        regimentOrderAddress.setCity(regiment.getCity());
        regimentOrderAddress.setArea(regiment.getArea());
        regimentOrderAddress.setAddress(regiment.getAddress());
        regimentOrderAddress.setName(regiment.getName());
        regimentOrderAddress.setType(3);
        regimentOrderAddress.setLastUpdateTime(new Date());
        regimentOrderAddress.setCreateBy(order.getUserId());
        regimentOrderAddress.setCreateTime(new Date());
        regimentOrderAddress.setStatus("0");
        regimentOrderAddress.setDelFlag("0");
        orderAddressService.save(regimentOrderAddress);
        return this.create(order);
    }


    @Override
    public Order createNewGoodsOrder(List<Goods> itemList, String userId, String appid, UserAddress receiverAddress, Long deptId) {
        if (!isValidPhoneNumber(receiverAddress.getMobile())) {
            throw new CustomException("不正确的手机号");
        }
        Order order = new Order();
        order.setId(IdUtil.getSnowflakeNextIdStr());
        order.setOrderTime(new Date());
        order.setOrderCode(generateShortCode());
        order.setOutTradeNo(this.generateOrderOutTradeNo(receiverAddress.getMobile(), System.currentTimeMillis()));
        order.setMobile(receiverAddress.getMobile());
        order.setAppid(appid);
        order.setProductCategory(2);
        order.setUserId(userId);
        order.setDeptId(deptId);
        order.setPayStatus(0);
        order.setOrderStatus(1);
        order.setTotalPrice(BigDecimal.ZERO);
        order.setCreateBy(userId);
        order.setOrderType(4);
        order.setDeliveryStatus(0);
        order.setCreateTime(new Date());
        order.setLastUpdateTime(new Date());
        List<OrderProduct> orderProducts = new ArrayList<>(itemList.size());
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (Goods item : itemList) {
            Goods goods = goodsService.get(item.getId());
            OrderProduct orderProduct = new OrderProduct();
            long id = IdUtil.getSnowflakeNextId();
            orderProduct.setId(String.valueOf(id));
            orderProduct.setCode(convertToFixedLengthHash(id));
            orderProduct.setOrderId(order.getId());
            orderProduct.setUserId(userId);
            orderProduct.setProductId(goods.getId());
            orderProduct.setWeight(goods.getWeight() == null ? BigDecimal.ZERO.toPlainString() : goods.getWeight().toPlainString());
            orderProduct.setTotalPrice(goods.getPrice());
            orderProduct.setPickUpPrice(BigDecimal.ZERO);
            orderProduct.setLastUpdateTime(new Date());
            orderProduct.setCreateTime(new Date());
            orderProduct.setStatus("0");
            orderProduct.setDelFlag("0");
            orderProducts.add(orderProduct);
            totalPrice = totalPrice.add(orderProduct.getTotalPrice());
            orderProductService.save(orderProduct);
            Dept dept = deptService.get(goods.getDeptId());
            OrderAddress merchantAddress = new OrderAddress();
            merchantAddress.setMobile(dept.getMobile());
            merchantAddress.setOrderId(order.getId());
            merchantAddress.setOrderProductId(orderProduct.getId());
            merchantAddress.setUserId(order.getUserId());
            merchantAddress.setProvince(dept.getProvince());
            merchantAddress.setCity(dept.getCity());
            merchantAddress.setArea(dept.getArea());
            merchantAddress.setAddress(dept.getAddress());
            merchantAddress.setName(dept.getName());
            merchantAddress.setRealName(dept.getRealName() == null ? dept.getName() : dept.getRealName());
            merchantAddress.setRealId(dept.getRealId());
            merchantAddress.setType(4);
            merchantAddress.setLastUpdateTime(new Date());
            merchantAddress.setCreateBy(order.getUserId());
            merchantAddress.setCreateTime(new Date());
            merchantAddress.setStatus("0");
            merchantAddress.setDelFlag("0");
            orderAddressService.save(merchantAddress);
        }
        order.setTotalPrice(new BigDecimal("100").multiply(totalPrice));
        Dept dept = deptService.get(deptId);
        OrderAddress regimentOrderAddress = new OrderAddress();
        OrderAddress receiverOrderAddress = new OrderAddress();
        receiverOrderAddress.setMobile(receiverAddress.getMobile());
        receiverOrderAddress.setOrderId(order.getId());
        receiverOrderAddress.setName(receiverAddress.getName());
        receiverOrderAddress.setUserId(receiverAddress.getUserId());
        receiverOrderAddress.setProvince(receiverAddress.getProvince());
        receiverOrderAddress.setCity(receiverAddress.getCity());
        receiverOrderAddress.setArea(receiverAddress.getArea());
        receiverOrderAddress.setTown(receiverAddress.getTown());
        receiverOrderAddress.setCode(receiverAddress.getCode());
        receiverOrderAddress.setAddress(receiverAddress.getAddress());
        receiverOrderAddress.setType(2);
        receiverOrderAddress.setLastUpdateTime(new Date());
        receiverOrderAddress.setCreateBy(order.getUserId());
        receiverOrderAddress.setCreateTime(new Date());
        receiverOrderAddress.setStatus("0");
        receiverOrderAddress.setDelFlag("0");
        orderAddressService.save(receiverOrderAddress);
        regimentOrderAddress.setMobile(dept.getMobile());
        regimentOrderAddress.setOrderId(order.getId());
        regimentOrderAddress.setUserId(order.getUserId());
        regimentOrderAddress.setProvince(dept.getProvince());
        regimentOrderAddress.setCity(dept.getCity());
        regimentOrderAddress.setArea(dept.getArea());
        regimentOrderAddress.setAddress(dept.getAddress());
        regimentOrderAddress.setName(dept.getDeptName());
        regimentOrderAddress.setType(3);
        regimentOrderAddress.setLastUpdateTime(new Date());
        regimentOrderAddress.setCreateBy(order.getUserId());
        regimentOrderAddress.setCreateTime(new Date());
        regimentOrderAddress.setStatus("0");
        regimentOrderAddress.setDelFlag("0");
        orderAddressService.save(regimentOrderAddress);
        order = this.create(order);
        return order;
    }

    @Override
    public OrderVo updateOrderProductCode(OrderProductCodeVo codeVo) {
        if (StringUtils.isBlank(codeVo.getCode()) || StringUtils.length(codeVo.getCode()) != 7) {
            throw new CustomException("条码不正确");
        }
        OrderProductCode productCode = orderProductCodeService.get(codeVo.getCode());
        OrderProduct op = orderProductService.query(codeVo.getCode());
        if (productCode != null || (op != null && !op.getId().equals(codeVo.getOrderProductId()))){
            throw new CustomException("此条码已使用");
        }
        User user = userService.get(codeVo.getUserId());
        if (user == null) {
            throw new CustomException("用户信息异常");
        }
        OrderProduct orderProduct = orderProductService.get(codeVo.getOrderProductId());
        if (StringUtils.isNotBlank(orderProduct.getCode())) {
            throw new CustomException("此商品已绑定条码");
        }
        Order order = this.get(codeVo.getOrderId());
        List<Role> roleList = userRoleService.getRoleList(codeVo.getUserId(), codeVo.getDeptId());
        if (!roleList.stream().filter(role -> role.getRoleKey().equalsIgnoreCase("REGIMENT")).findAny().isPresent()) {
            throw new CustomException("权限不足");
        }
        Role role = roleList.stream().filter(r -> "REGIMENT".equals(r.getRoleKey())).findFirst().get();
        OrderProductCode orderProductCode = new OrderProductCode();
        orderProductCode.setId(IdUtil.getSnowflakeNextIdStr());
        orderProductCode.setCode(codeVo.getCode());
        orderProductCode.setBatchNo(orderProductCodeService.getNextBatchNo(user.getId()));
        orderProductCode.setUserId(codeVo.getUserId());
        orderProductCode.setDeptId(codeVo.getDeptId());
        orderProductCode.setCreateBy(codeVo.getUserId());
        orderProductCode.setStatus(1);
        orderProductCodeService.save(orderProductCode);
        orderProduct.setCode(codeVo.getCode());
        orderProduct.setUpdateBy(codeVo.getUserId());
        orderProduct.setUpdateTime(new Date());
        orderProductService.update(orderProduct);
        userOrderEventService.addInitEvent(codeVo.getUserId(), codeVo.getDeptId(), order.getId(), orderProduct.getId());
        orderLogisticsService.addOrderLogistics(orderProduct.getOrderId(), orderProduct.getId(), 1, codeVo.getUserId(), codeVo.getDeptId(), true);
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
        if (!orderProductList.stream().filter(o -> StringUtils.isBlank(o.getCode())).findAny().isPresent()) {
            try {
                orderShipments(order.getId(), codeVo.getUserId());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return this.getDetail(order.getId());
    }

    @Override
    public Order updateCartOrder(String orderId, List<SysCartItem> cartItems, String userId) {
        Order order = this.get(orderId);
        order.setTotalPrice(BigDecimal.ZERO);
        order.setRegimentId(userId);
        order.setUpdateBy(userId);
        order.setUpdateTime(new Date());
        order.setLastUpdateTime(new Date());
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(orderId);
        List<SysCartItem> cartItemList = orderProductList.stream().map(product -> cartItemService.get(product.getCartItemId())).collect(Collectors.toList());
        Map<Long, SysCartItem> cartItemMap = cartItemList.stream().collect(Collectors.toMap(e -> e.getId(), e -> e));
        Map<String, OrderProduct> orderProductMap = orderProductList.stream().collect(Collectors.toMap(e -> e.getId(), e -> e));
        List<OrderProduct> orderProducts = new ArrayList<>(cartItems.size());
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (SysCartItem cartItem : cartItems) {
            if (cartItemMap.containsKey(cartItem.getId())) {
                SysCartItem item = cartItemMap.get(cartItem.getId());
                OrderProduct orderProduct = orderProductService.getCartItemProduct(order.getId(), item.getId());
                BigDecimal price = cartItem.getTotalPrice();
                orderProduct.setTotalPrice(price);
                orderProduct.setPickUpPrice(BigDecimal.ZERO);
                orderProduct.setUpdateTime(new Date());
                orderProduct.setUpdateBy(userId);
                orderProductService.update(orderProduct);
                totalPrice = totalPrice.add(price);
                cartItemMap.remove(cartItem.getId());
            } else {
                OrderProduct orderProduct = new OrderProduct();
                orderProduct.setId(IdUtil.getSnowflakeNextIdStr());
                orderProduct.setOrderId(order.getId());
                orderProduct.setUserId(userId);
                orderProduct.setCartItemId(cartItem.getId());
                orderProduct.setProductId(cartItem.getProductId());
                BigDecimal price = cartItem.getTotalPrice();
                orderProduct.setTotalPrice(price);
                orderProduct.setPickUpPrice(BigDecimal.ZERO);
                orderProduct.setLastUpdateTime(new Date());
                orderProduct.setCreateTime(new Date());
                orderProduct.setStatus("0");
                orderProduct.setDelFlag("0");
                orderProducts.add(orderProduct);
                totalPrice = totalPrice.add(price);
                orderProductService.save(orderProduct);
            }
        }
        for (SysCartItem cartItem : cartItemMap.values()) {
            cartItem.setStatus("0");
            cartItem.setUpdateTime(new Date());
            cartItem.setUpdateBy(userId);
            cartItemService.update(cartItem);
        }
        order.setTotalPrice(new BigDecimal("100").multiply(totalPrice));
        order.setUpdateTime(new Date());
        order.setUpdateBy(userId);
        this.update(order);
        return order;
    }

    public static String convertToFixedLengthHash(long data) {
        try {
            // 使用MD5哈希函数
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 将长整型数据转换为字节数组
            byte[] bytes = BigInteger.valueOf(data).toByteArray();
            // 计算哈希值
            byte[] digest = md.digest(bytes);
            // 取哈希值的前4个字节，并转换成正整数
            int hash = Math.abs(new BigInteger(1, digest).intValue());
            // 将哈希值转换成8位编码
            String encoded = Integer.toString(hash, 36);
            // 如果长度不足8位，在前面补0
            while (encoded.length() < 8) {
                encoded = "0" + encoded;
            }
            // 截取前8位作为编码
            return encoded.substring(0, 8).toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public boolean updateRefundLogistic(String orderId, String orderProductId, String userId, Long deptId) {
        Order order = this.get(orderId);
        if (order.getOrderStatus() != 4) {
            throw new CustomException("该订单未退款");
        }
        OrderProduct orderProduct = orderProductService.get(orderProductId);
        Integer eventType = orderLogisticsService.getLatestOrderProductEventType(order.getId(), orderProduct.getId());
        userOrderEventService.lastEvent(order.getId(), orderProduct.getId(), eventType);
        UserOrderEvent event = userOrderEventService.getUserOrderEvent(userId, deptId, orderId, orderProductId, 2, "0");
        event.setStatus("2");
        event.setUpdateTime(new Date());
        event.setUpdateBy(userId);
        userOrderEventService.update(event);
        userOrderEventService.addUserData(userId, deptId, order.getId(), orderProduct.getId(), LogisticsEventEnum.FACTORY_COMPLETE.getType());
        UserOrderEvent refundOrderEvent = userOrderEventService.getUserOrderEvent(userId, deptId, orderId, orderProductId, 3, "0");
        refundOrderEvent.setStatus("1");
        refundOrderEvent.setUpdateTime(new Date());
        refundOrderEvent.setUpdateBy(userId);
        userOrderEventService.update(refundOrderEvent);
        return orderLogisticsService.addOrderLogistics(true, orderId, orderProduct.getId(), LogisticsEventEnum.FACTORY_COMPLETE.getType(), userId, deptId);
    }

    @Override
    public Object getWaybillNo(String orderId, List<String> orderProductIds, String deliveryId, String userId) {
        List<OrderProduct> orderProductList = new ArrayList<>();
        orderProductIds.forEach(id -> orderProductList.add(orderProductService.get(id)));
        List<OrderAddress> addressList = orderAddressService.getAddressList(orderId);
        OrderAddress senderAddress = addressList.stream().filter(orderAddress -> orderAddress.getType() == 4).findFirst().get();
        OrderAddress receiverAddress = addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().get();
        return logisticService.createOrder(orderId, deliveryId, senderAddress, receiverAddress, orderProductList);
    }

    @Override
    public Object findOrderByOrderProductCode(String code) {
        OrderProduct orderProduct = orderProductService.query(code);
        if (orderProduct == null){
            throw new CustomException("【" + code + "】该编码不存在");
        }
        OrderVo detail = this.getDetail(orderProduct.getOrderId());
        List<OrderProduct> productList = detail.getProductList();
        return detail;
    }

    @Override
    public List<OrderPayment> findExportOrderData(String userId, String startDate, String endDate) {
        List<OrderPayment> orderList = orderMapper.selectGroupLeaderList2(userId, null ,startDate, endDate,0);
        List<OrderPayment> exportData = new ArrayList<>(orderList.size() * 2);
        for (OrderPayment order : orderList) {
            List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getOrderId());
            if (!CollectionUtils.isEmpty(orderProductList)) {
                StringBuilder businessDesc = new StringBuilder();
                for (int i = 0; i < orderProductList.size(); i++) {
                    OrderProduct orderProduct = orderProductList.get(i);
                    Goods goods = goodsService.get(orderProduct.getProductId());
                    // 拼接商品信息
                    businessDesc.append((goods.getKeywords() == null ? "" : goods.getKeywords()))
                            .append(goods.getName())
                            .append("   *   ")
                            .append(orderProduct.getQuantity() == null ? "1" : orderProduct.getQuantity());
                    // 如果不是最后一个商品，添加换行符
                    if (i != orderProductList.size() - 1) {
                        businessDesc.append("\n");
                    }
                }
                // 将拼接的内容用双引号包裹，确保换行符在CSV中生效
                String businessDescription = "\"" + businessDesc.toString().replace("\"", "\"\"") + "\"";
                order.setBusinessDescription(businessDescription);
            }
            exportData.add(order);
        }
        return exportData;
    }


    @Override
    public void orderShipments(String orderId, String userId) {
        Order order = this.get(orderId);
        order.setDeliveryStatus(1);
        order.setUpdateBy(userId);
        order.setUpdateTime(new Date());
//        if (order.getOrderType() == 2){
//            String appid = order.getAppid();
//            String accessToken = wechatService.getAccessToken(appid, clientConfig.getAppid().equals(appid) ? clientConfig.getSecret() : manageConfig.getSecret());
//            wechatService.notifyConfirmReceive(order.getTransactionId(), null,  order.getOutTradeNo(), accessToken);
//        }
        if (order.getOrderType() == 2){
            sendLaundryShippingMessage(order.getId());
        }
        if (order.getOrderType() == 4){
            List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
            String itemDesc = null;
            if (!CollectionUtils.isEmpty(orderProductList)) {
                StringBuilder businessDesc = new StringBuilder();
                for (int i = 0; i < orderProductList.size(); i++) {
                    Goods goods = goodsService.get(orderProductList.get(i).getProductId());
                    // 拼接商品信息
                    businessDesc.append(goods.getName());
                    // 如果不是最后一个商品，添加换行符
                    if (i != orderProductList.size() - 1) {
                        businessDesc.append("\n");
                    }
                }
                // 将拼接的内容用双引号包裹，确保换行符在CSV中生效
                itemDesc = "\"" + businessDesc.toString().replace("\"", "\"\"") + "\"";
            }
            User payer = userService.get(order.getPayerId());
            String appid = payer.getAppid();
            String accessToken = wechatService.getAccessToken(appid, clientConfig.getAppid().equals(appid) ? clientConfig.getSecret() : manageConfig.getSecret());
            List<OrderAddress> addressList = orderAddressService.getAddressList(order.getId());
            OrderAddress userAddress = null;
            OrderAddress deptAddress = null;
            if (addressList.stream().filter(address -> address.getType() == 2).findFirst().isPresent()) {
                userAddress = addressList.stream().filter(address -> address.getType() == 2).findFirst().get();
            }
            if (addressList.stream().filter(address -> address.getType() == 3).findFirst().isPresent()) {
                deptAddress = addressList.stream().filter(address -> address.getType() == 3).findFirst().get();
            }
            wechatService.uploadShippingInfo(order.getTransactionId(), "", "", itemDesc, order.getPayerId(), deptAddress != null ? deptAddress.getMobile() : "", userAddress != null ? userAddress.getMobile() : "", 2,  accessToken);
        }
        order.setShippedTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public Order getByTransactionId(String transactionId) {
        return orderMapper.selectByTransactionId(transactionId);
    }

    @Override
    public void receiveNotify(String orderId, String userId) {
        Order order = this.get(orderId);
        if (order.getOrderType() == 2){
            String accessToken = wechatService.getAccessToken(order.getAppid(), clientConfig.getAppid().equals(order.getAppid()) ? clientConfig.getSecret() : manageConfig.getSecret());
            wechatService.notifyConfirmReceive(order.getTransactionId(), "", "", accessToken);
        }
    }

    @Override
    public void sendLaundryShippingMessage(String orderId) {
        Order order = get(orderId);
        List<OrderProduct> orderProductList = orderProductService.getOrderProductList(order.getId());
        String itemDesc = null;
        if (!CollectionUtils.isEmpty(orderProductList)) {
            StringBuilder businessDesc = new StringBuilder();
            for (int i = 0; i < orderProductList.size(); i++) {
                OrderProduct orderProduct = orderProductList.get(i);
                SysCartItem cartItem = cartItemService.get(orderProduct.getCartItemId());
                SysProduct product = productService.get(orderProduct.getProductId());
                // 拼接商品信息
                businessDesc.append((product.getKeywords() == null ? "" : product.getKeywords()))
                        .append(product.getName())
                        .append("   *   ")
                        .append(cartItem.getQuantity());
                // 如果不是最后一个商品，添加换行符
                if (i != orderProductList.size() - 1) {
                    businessDesc.append("\n");
                }
            }
            // 将拼接的内容用双引号包裹，确保换行符在CSV中生效
            itemDesc = "\"" + businessDesc.toString().replace("\"", "\"\"") + "\"";
        }
        User payer = userService.get(order.getPayerId());
        String appid = payer.getAppid();
        String accessToken = wechatService.getAccessToken(appid, clientConfig.getAppid().equals(appid) ? clientConfig.getSecret() : manageConfig.getSecret());
        List<OrderAddress> addressList = orderAddressService.getAddressList(order.getId());
        OrderAddress orderAddress = null;
        OrderAddress deptAddress = null;
        if (addressList.stream().filter(address -> address.getType() == 2).findFirst().isPresent()) {
            orderAddress = addressList.stream().filter(address -> address.getType() == 2).findFirst().get();
        }
        if (addressList.stream().filter(address -> address.getType() == 3).findFirst().isPresent()) {
            deptAddress = addressList.stream().filter(address -> address.getType() == 3).findFirst().get();
        }
        wechatService.uploadShippingInfo(order.getTransactionId(), order.getOrderCode(), "ZY_YGKD", itemDesc, order.getPayerId(), deptAddress != null ? deptAddress.getMobile() : "", orderAddress != null ? orderAddress.getMobile() : "", 1, accessToken);
    }

    @Override
    public void delete(String userId) {
    }

    private Integer calculateMethodAOrderPrice_JTSD(Integer weight, String province, String deliveryId) {
        // 新疆：首重15（12）+续重10（8）
        // 海南：首重12（8）+续重5（3）
        // 西藏：首重18（15）+续重12（10）
        // 内蒙古：首重10（8）+续重6（5）（阔内为团长成本）仅 极兔申通
        if (province.contains("新疆")) {
            return DeliveryEnum.EMS.toString().equals(deliveryId) ? priceA_JTSD(weight, 20, 15) : priceA_JTSD(weight, 15, 10);
        } else if (province.contains("海南")) {
            return priceA_JTSD(weight, 12, 5);
        } else if (province.contains("西藏")) {
            return DeliveryEnum.EMS.toString().equals(deliveryId) ? priceA_JTSD(weight, 20, 15) : priceA_JTSD(weight, 15, 12);
        } else if (province.contains("内蒙古") && ("JTSD".equals(deliveryId) || "STO".equals(deliveryId))) {
            return priceA_JTSD(weight, 10, 6);
        } else if (province.contains("北京") || province.contains("上海")) {
            return priceA_JTSD(weight, 25) + 100;
        } else if (province.contains("青海") && DeliveryEnum.EMS.toString().equals(deliveryId)) {
            return priceA_JTSD(weight, 20, 15);
        } else {
            return priceA_JTSD(weight, 25);
        }
    }

    private Integer calculateMethodAOrderPrice(Integer weight, String province, String deliveryId) {
        // 新疆：首重15（12）+续重10（8）
        // 海南：首重12（8）+续重5（3）
        // 西藏：首重18（15）+续重12（10）
        // 内蒙古：首重10（8）+续重6（5）（阔内为团长成本）仅 极兔申通
        if (province.contains("新疆")) {
            return DeliveryEnum.EMS.toString().equals(deliveryId) ? priceA(weight, 20, 15) : priceA(weight, 15, 10);
        } else if (province.contains("海南")) {
            return priceA(weight, 12, 5);
        } else if (province.contains("西藏")) {
            return DeliveryEnum.EMS.toString().equals(deliveryId) ? priceA(weight, 20, 15) : priceA(weight, 15, 12);
        } else if (province.contains("内蒙古") && ("JTSD".equals(deliveryId) || "STO".equals(deliveryId))) {
            return priceA(weight, 10, 6);
        } else if (province.contains("北京") || province.contains("上海")) {
            return priceA(weight, 25) + 100;
        } else if (province.contains("青海") && DeliveryEnum.EMS.toString().equals(deliveryId)) {
            return priceA(weight, 20, 15);
        } else {
            return priceA(weight, 25);
        }
    }

    private Integer calculateMethodBOrderPrice(Integer weight, String province, String deliveryId) {
        // 新疆：首重15（12）+续重10（8）
        // 海南：首重12（8）+续重5（3）
        // 西藏：首重18（15）+续重12（10）
        // 内蒙古：首重10（8）+续重6（5）（阔内为团长成本）仅 极兔申通
        if (province.contains("新疆")) {
            return DeliveryEnum.EMS.toString().equals(deliveryId) ? priceA(weight, 20, 15) : priceA(weight, 15, 10);
        } else if (province.contains("海南")) {
            return priceA(weight, 12, 5);
        } else if (province.contains("西藏")) {
            return DeliveryEnum.EMS.toString().equals(deliveryId) ? priceA(weight, 20, 15) : priceA(weight, 15, 12);
        } else if (province.contains("内蒙古") && ("JTSD".equals(deliveryId) || "STO".equals(deliveryId))) {
            return priceA(weight, 10, 6);
        } else if (province.contains("北京") || province.contains("上海")) {
            return priceB(weight, 30) + 100;
        } else if (province.contains("青海") && DeliveryEnum.EMS.toString().equals(deliveryId)) {
            return priceA(weight, 20, 15);
        } else {
            return priceB(weight, 30);
        }
    }

    private Integer calculateEMSCost(Integer weight, String province, String deliveryId) {
        if (province.contains("新疆")) {
            return priceA(weight, 20, 15);
        } else if (province.contains("海南")) {
            return priceA(weight, 12, 5);
        } else if (province.contains("西藏")) {
            return priceA(weight, 20, 15);
        } else if (province.contains("内蒙古") && ("JTSD".equals(deliveryId) || "STO".equals(deliveryId))) {
            return priceA(weight, 10, 6);
        } else if (province.contains("北京") || province.contains("上海")) {
            return priceB(weight, 30) + 100;
        } else if (province.contains("青海")) {
            return priceA(weight, 20, 15);
        } else {
            return calculateCost(weight);
        }
    }


    public static int calculateCost(Integer weight) {
        if (weight <= 0) {
            throw new IllegalArgumentException("重量必须大于0");
        }
        // 1公斤到3公斤的固定价格
        if (weight == 1) {
            return 600;
        } else if (weight == 2) {
            return 800;
        } else if (weight == 3) {
            return 900;
        }
        // 4公斤及以上的计算规则
        if (weight >= 4) {
            return (12 + (weight - 4) * 3) * 100;
        }
        // 默认返回0（理论上不会走到这里）
        return 0;
    }
    private Integer priceA_JTSD(Integer weight, Integer first, Integer plus) {
        return (weight * plus + (first - plus)) * 100;
    }

    private Integer priceA_JTSD(Integer weight, Integer coefficient) {
        switch (weight) {
            case 1:
                return 5 * 100;
            case 2:
                return 7 * 100;
            case 3:
                return 8 * 100;
            default:
                return weight * coefficient * 10;
        }
    }
    private Integer priceA(Integer weight, Integer first, Integer plus) {
        return (weight * plus + (first - plus)) * 100;
    }

    private Integer priceA(Integer weight, Integer coefficient) {
        switch (weight) {
            case 1:
                return 6 * 100;
            case 2:
                return 7 * 100;
            case 3:
                return 8 * 100;
            default:
                return weight * coefficient * 10;
        }
    }

    private Integer priceB(Integer weight, Integer coefficient) {
        switch (weight) {
            case 1:
                return 6 * 100;
            case 2:
                return 8 * 100;
            case 3:
                return 10 * 100;
            default:
                return weight * coefficient * 10;
        }
    }


    public static boolean isValidPhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.trim().isEmpty()) {
            return false;
        }
        return phoneNumber.matches(PHONE_NUMBER_PATTERN);
    }

}
